Maarten Lankhorst : winmm: Make timer keep a ref on winmm while it' s running.
Alexandre Julliard
julliard at winehq.org
Wed May 19 10:34:15 CDT 2010
Module: wine
Branch: master
Commit: 00eaa9294559bb75cf5cbf7f1b61c3e239d08d62
URL: http://source.winehq.org/git/wine.git/?a=commit;h=00eaa9294559bb75cf5cbf7f1b61c3e239d08d62
Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date: Mon May 17 19:58:28 2010 +0200
winmm: Make timer keep a ref on winmm while it's running.
---
dlls/winmm/time.c | 43 +++++++++++++++++++++++--------------------
1 files changed, 23 insertions(+), 20 deletions(-)
diff --git a/dlls/winmm/time.c b/dlls/winmm/time.c
index ee835c7..3d45fd9 100644
--- a/dlls/winmm/time.c
+++ b/dlls/winmm/time.c
@@ -138,7 +138,6 @@ static int TIME_MMSysTimeCallback(void)
* mm timer crit sect locked.
*/
- EnterCriticalSection(&WINMM_cs);
for (;;)
{
struct list *ptr = list_head( &timer_list );
@@ -188,7 +187,6 @@ static int TIME_MMSysTimeCallback(void)
}
HeapFree( GetProcessHeap(), 0, to_free );
}
- LeaveCriticalSection(&WINMM_cs);
return delta_time;
}
@@ -206,20 +204,21 @@ static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg)
TRACE("Starting main winmm thread\n");
- /* FIXME: As an optimization, we could have
- this thread die when there are no more requests
- pending, and then get recreated on the first
- new event; it's not clear if that would be worth
- it or not. */
-
+ EnterCriticalSection(&WINMM_cs);
while (! TIME_TimeToDie)
{
sleep_time = TIME_MMSysTimeCallback();
+ if (sleep_time < 0)
+ break;
if (sleep_time == 0)
continue;
- if ((ret = poll(&pfd, 1, sleep_time)) < 0)
+ LeaveCriticalSection(&WINMM_cs);
+ ret = poll(&pfd, 1, sleep_time);
+ EnterCriticalSection(&WINMM_cs);
+
+ if (ret < 0)
{
if (errno != EINTR && errno != EAGAIN)
{
@@ -230,7 +229,11 @@ static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg)
while (ret > 0) ret = read(TIME_fdWake[0], readme, sizeof(readme));
}
+ CloseHandle(TIME_hMMTimer);
+ TIME_hMMTimer = NULL;
+ LeaveCriticalSection(&WINMM_cs);
TRACE("Exiting main winmm thread\n");
+ FreeLibraryAndExitThread(arg, 0);
return 0;
}
@@ -239,7 +242,9 @@ static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg)
*/
static void TIME_MMTimeStart(void)
{
+ TIME_TimeToDie = 0;
if (!TIME_hMMTimer) {
+ HMODULE mod;
if (pipe(TIME_fdWake) < 0)
{
TIME_fdWake[0] = TIME_fdWake[1] = -1;
@@ -248,8 +253,8 @@ static void TIME_MMTimeStart(void)
fcntl(TIME_fdWake[0], F_SETFL, O_NONBLOCK);
fcntl(TIME_fdWake[1], F_SETFL, O_NONBLOCK);
}
- TIME_TimeToDie = FALSE;
- TIME_hMMTimer = CreateThread(NULL, 0, TIME_MMSysTimeThread, NULL, 0, NULL);
+ GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)TIME_MMSysTimeThread, &mod);
+ TIME_hMMTimer = CreateThread(NULL, 0, TIME_MMSysTimeThread, mod, 0, NULL);
SetThreadPriority(TIME_hMMTimer, THREAD_PRIORITY_TIME_CRITICAL);
}
}
@@ -269,17 +274,13 @@ static void TIME_MMTimeStart(void)
void TIME_MMTimeStop(void)
{
if (TIME_hMMTimer) {
- const char a='a';
-
- TIME_TimeToDie = TRUE;
- write(TIME_fdWake[1], &a, sizeof(a));
-
- WaitForSingleObject(TIME_hMMTimer, INFINITE);
+ EnterCriticalSection(&WINMM_cs);
+ if (TIME_hMMTimer) {
+ ERR("Timer still active?!\n");
+ CloseHandle(TIME_hMMTimer);
+ }
close(TIME_fdWake[0]);
close(TIME_fdWake[1]);
- TIME_fdWake[0] = TIME_fdWake[1] = -1;
- CloseHandle(TIME_hMMTimer);
- TIME_hMMTimer = 0;
DeleteCriticalSection(&TIME_cbcrst);
}
}
@@ -368,6 +369,8 @@ MMRESULT WINAPI timeKillEvent(UINT wID)
break;
}
}
+ if (list_empty(&timer_list))
+ TIME_TimeToDie = 1;
LeaveCriticalSection(&WINMM_cs);
if (!lpSelf)
More information about the wine-cvs
mailing list