http://bugs.winehq.org/show_bug.cgi?id=10343
Summary: SetTimer won't wait for specified time Product: Wine Version: 0.9.48. Platform: PC OS/Version: Linux Status: UNCONFIRMED Severity: major Priority: P2 Component: wine-user AssignedTo: wine-bugs@winehq.org ReportedBy: dmda@yandex.ru
Windows supports the following semantic for SetTimer():
hTimer = SetTimer(0, MY_ID, TIMEOUT, NULL); note: hWnd is zero, callback is NULL.
In this case Windows sends WM_TIMER to the thread queue after specified TIMEOUT milliseconds with wParam==hTimer returned by the function (not MY_ID! and this is because of zero hWnd!) When SetTimer is called this way it returns somewhat special in hTimer, for example 0x7edc.
Under wine, it returns 1 and sends WM_TIMER immediately, regardless of TIMEOUT (I tried with 6000ms==6s)
Reference: MSDN: If the function succeeds and the hWnd parameter is NULL, the return value is an integer identifying the new timer. An application can pass this value to the KillTimer function to destroy the timer.
http://bugs.winehq.org/show_bug.cgi?id=10343
--- Comment #1 from Dmitry Timoshkov dmitry@codeweavers.com 2007-11-07 21:00:26 --- Can you add a test that shows the problem to dlls/user32/tests/msg.c, test_timers()? So far my reading of appropriate wineserver code reveals that it conforms to your description/expectation.
http://bugs.winehq.org/show_bug.cgi?id=10343
--- Comment #2 from jvlad dmda@yandex.ru 2007-11-08 17:45:31 --- I created test case (even two) and was unable to replicate the problem.
Then I went deeper into the original faulting application and found out that there was a conflict between ID I used for the application main window timer and ID returned by SetTimer with zero hWnd. So the window's timer that triggers quite frequently was recognized as an application-wide timer so I thought that the timeout value I set for it had no effect.
I'm not sure if you can fix this problem in any other way but use quite high values for returning from SetTimer when zero hWnd is supplied like Windows does. Windows always returns IDs somewhere from 0x7d00 and higher. Wine returned 0x1 and it's what I use :) for my main window.
http://bugs.winehq.org/show_bug.cgi?id=10343
--- Comment #3 from Dmitry Timoshkov dmitry@codeweavers.com 2007-11-08 20:29:11 --- Perhaps you could still write a test demonstrating that Wine allocates a timer id that's already in use?
http://bugs.winehq.org/show_bug.cgi?id=10343
--- Comment #4 from jvlad dmda@yandex.ru 2007-11-09 11:16:43 --- not exactly, how would it know timer IDs used somewhere in the application, especially if they are not used up to the moment when SetTimer with NULL hWnd is called? Windows solves this by assigning quite high values in assumption that user uses quite low values for the timers he creates on non-NULL windows.
In details, suppose I have POLL_TIMER_ID=0x1 that I use for my main window. Theoretically it's okay when SetTimer assigns 0x1 for the NULL window too because I can capture window's WM_TIMER in its wndproc while NULL-ish timer can be captured in the GetMessage loop. All is fine, except that window's WM_TIMER is passed through the GetMessage loop too and since it has the same ID it may create problems (and actually created them for me).
http://bugs.winehq.org/show_bug.cgi?id=10343
--- Comment #5 from Dmitry Timoshkov dmitry@codeweavers.com 2007-11-11 21:19:57 --- You (as a developer of the application) opened a bug report stating that Wine behaviour is not correct. But once asked to write a test case to show/ reproduce the problem (since as a developer you have the sources around, but not anyone else wishing to help fixing this) you say that the problem does not really exist/impossible to reproduce.
If you don't want to demonstrate the problem, this bug will be marked as invalid or abandoned.
http://bugs.winehq.org/show_bug.cgi?id=10343
--- Comment #6 from jvlad dmda@yandex.ru 2007-11-12 12:42:39 ---
#define MY_ID 1000 #define TIMEOUT 6000
...
hTimer = SetTimer(0, MY_ID, TIMEOUT, NULL); assert(hTimer > 0x7000);
if you're not satisfied with test case above, please read my notes one more time and proceed appropriately. I have quite nothing to add.
http://bugs.winehq.org/show_bug.cgi?id=10343
Vitaliy Margolen vitaliy@kievinfo.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution| |INVALID
--- Comment #7 from Vitaliy Margolen vitaliy@kievinfo.com 2007-11-12 18:29:55 --- (In reply to comment #6)
#define MY_ID 1000 #define TIMEOUT 6000
...
hTimer = SetTimer(0, MY_ID, TIMEOUT, NULL); assert(hTimer > 0x7000);
if you're not satisfied with test case above, please read my notes one more time and proceed appropriately. I have quite nothing to add.
This test is invalid. From MSDN: "If the function succeeds and the hWnd parameter is NULL, the return value is an integer identifying the new timer."
"integer" the UINT_PTR type is 64-bit unsigned int. Which can have _ANY_ value, including 1.
So _assuming_ anything that is not documented is wrong. Which makes the bug in your program.
Closing invalid as you failed to demonstrate the problem. Yet you showed that bug in your own code.
http://bugs.winehq.org/show_bug.cgi?id=10343
--- Comment #8 from jvlad dmda@yandex.ru 2007-11-12 19:49:12 --- Dmitry, if you read my note with a some degree of politeness, you'd find out that I said Windows assigns safer IDs to timers, than "one" that often used for IDs created by users. Right, it's not documented that Windows takes precautions and what does it change? It's just yet another poorly documented feature of Windows and if you don't try to follow it, you'd possibly create compatibility problems for the other applications as well. I thought that you'd care of this. And from the perspectives said above, would you please point me out onto where the test case is invalid?
http://bugs.winehq.org/show_bug.cgi?id=10343
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net
--- Comment #9 from Anastasius Focht focht@gmx.net 2007-11-13 03:28:14 --- Hello,
--- quote --- "integer" the UINT_PTR type is 64-bit unsigned int. Which can have _ANY_ value, including 1. --- quote ---
For the "joe average" programmer who doesn't question anything written this statement might be the true but we all know from the technical standpoint [under the hood] MSDN this isn't always right. Having worked many years with the win32 API/kernel i've encountered countless bugs/quirks documented and undocumented that I hardly believe in anything written because it says "MSDN". Back to topic ;-)
It is true that windows reserves a specific range from which it allocates timer id's for newly created timer objects. Usually between 0x3E8 (min timer id) and 0x7FFF (max timer id). Though numbers might slightly differ, depending on windows version.
The important fact is: timer id's are allocated backwards, starting from "max timer id" until "min timer id" is reached. It then wraps around to max again. If the timer id space is exhausted, creation of new timers is denied.
Proof? Write a simple loop which repeatedly calls SetTimer() and keeps track of returned timer id's.
In my opinion wine should at least mimick the "backwards allocate timer id's from max. value" of windows. Wine's timer id allocation scheme might trigger side effects in broken windows apps.
Regards
http://bugs.winehq.org/show_bug.cgi?id=10343
Dmitry Timoshkov dmitry@codeweavers.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |UNCONFIRMED Resolution|INVALID |
--- Comment #10 from Dmitry Timoshkov dmitry@codeweavers.com 2007-11-13 05:05:34 --- (In reply to comment #8)
Dmitry, if you read my note with a some degree of politeness, you'd find out that I said Windows assigns safer IDs to timers, than "one" that often used for IDs created by users. Right, it's not documented that Windows takes precautions and what does it change? It's just yet another poorly documented feature of Windows and if you don't try to follow it, you'd possibly create compatibility problems for the other applications as well. I thought that you'd care of this. And from the perspectives said above, would you please point me out onto where the test case is invalid?
The test case is perfectly valid, it's not me who calls it invalid.
As Anastasius explained we at least need to change the timer id allocation algorithm to make it go backwards.
http://bugs.winehq.org/show_bug.cgi?id=10343
--- Comment #11 from jvlad dmda@yandex.ru 2007-11-13 06:09:54 --- it's a much better approach and quite corresponds to advertized "bug for bug and feature for feature" compatibility between wine and windows.
http://bugs.winehq.org/show_bug.cgi?id=10343
--- Comment #12 from Dmitry Timoshkov dmitry@codeweavers.com 2007-11-13 09:20:09 --- I sent a patch which should make the timer id allocation algorithm better conform to a Windows one:
http://www.winehq.org/pipermail/wine-patches/2007-November/046692.html
http://bugs.winehq.org/show_bug.cgi?id=10343
Dmitry Timoshkov dmitry@codeweavers.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution| |FIXED
--- Comment #13 from Dmitry Timoshkov dmitry@codeweavers.com 2007-11-14 09:12:45 --- The patch was committed.
http://bugs.winehq.org/show_bug.cgi?id=10343
Dan Kegel dank@kegel.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #14 from Dan Kegel dank@kegel.com 2008-01-28 05:40:53 --- Closing all RESOLVED FIXED bugs older than four weeks.
http://bugs.winehq.org/show_bug.cgi?id=10343
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Fixed by SHA1| |b4227d7207424823b787feddc3a | |7fba095594974 Component|user32 |wineserver