Commit 00eaa929 authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Alexandre Julliard

winmm: Make timer keep a ref on winmm while it's running.

parent cc784e27
...@@ -138,7 +138,6 @@ static int TIME_MMSysTimeCallback(void) ...@@ -138,7 +138,6 @@ static int TIME_MMSysTimeCallback(void)
* mm timer crit sect locked. * mm timer crit sect locked.
*/ */
EnterCriticalSection(&WINMM_cs);
for (;;) for (;;)
{ {
struct list *ptr = list_head( &timer_list ); struct list *ptr = list_head( &timer_list );
...@@ -188,7 +187,6 @@ static int TIME_MMSysTimeCallback(void) ...@@ -188,7 +187,6 @@ static int TIME_MMSysTimeCallback(void)
} }
HeapFree( GetProcessHeap(), 0, to_free ); HeapFree( GetProcessHeap(), 0, to_free );
} }
LeaveCriticalSection(&WINMM_cs);
return delta_time; return delta_time;
} }
...@@ -206,20 +204,21 @@ static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg) ...@@ -206,20 +204,21 @@ static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg)
TRACE("Starting main winmm thread\n"); TRACE("Starting main winmm thread\n");
/* FIXME: As an optimization, we could have EnterCriticalSection(&WINMM_cs);
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. */
while (! TIME_TimeToDie) while (! TIME_TimeToDie)
{ {
sleep_time = TIME_MMSysTimeCallback(); sleep_time = TIME_MMSysTimeCallback();
if (sleep_time < 0)
break;
if (sleep_time == 0) if (sleep_time == 0)
continue; 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) if (errno != EINTR && errno != EAGAIN)
{ {
...@@ -230,7 +229,11 @@ static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg) ...@@ -230,7 +229,11 @@ static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg)
while (ret > 0) ret = read(TIME_fdWake[0], readme, sizeof(readme)); 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"); TRACE("Exiting main winmm thread\n");
FreeLibraryAndExitThread(arg, 0);
return 0; return 0;
} }
...@@ -239,7 +242,9 @@ static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg) ...@@ -239,7 +242,9 @@ static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg)
*/ */
static void TIME_MMTimeStart(void) static void TIME_MMTimeStart(void)
{ {
TIME_TimeToDie = 0;
if (!TIME_hMMTimer) { if (!TIME_hMMTimer) {
HMODULE mod;
if (pipe(TIME_fdWake) < 0) if (pipe(TIME_fdWake) < 0)
{ {
TIME_fdWake[0] = TIME_fdWake[1] = -1; TIME_fdWake[0] = TIME_fdWake[1] = -1;
...@@ -248,8 +253,8 @@ static void TIME_MMTimeStart(void) ...@@ -248,8 +253,8 @@ static void TIME_MMTimeStart(void)
fcntl(TIME_fdWake[0], F_SETFL, O_NONBLOCK); fcntl(TIME_fdWake[0], F_SETFL, O_NONBLOCK);
fcntl(TIME_fdWake[1], F_SETFL, O_NONBLOCK); fcntl(TIME_fdWake[1], F_SETFL, O_NONBLOCK);
} }
TIME_TimeToDie = FALSE; GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)TIME_MMSysTimeThread, &mod);
TIME_hMMTimer = CreateThread(NULL, 0, TIME_MMSysTimeThread, NULL, 0, NULL); TIME_hMMTimer = CreateThread(NULL, 0, TIME_MMSysTimeThread, mod, 0, NULL);
SetThreadPriority(TIME_hMMTimer, THREAD_PRIORITY_TIME_CRITICAL); SetThreadPriority(TIME_hMMTimer, THREAD_PRIORITY_TIME_CRITICAL);
} }
} }
...@@ -269,17 +274,13 @@ static void TIME_MMTimeStart(void) ...@@ -269,17 +274,13 @@ static void TIME_MMTimeStart(void)
void TIME_MMTimeStop(void) void TIME_MMTimeStop(void)
{ {
if (TIME_hMMTimer) { if (TIME_hMMTimer) {
const char a='a'; EnterCriticalSection(&WINMM_cs);
if (TIME_hMMTimer) {
TIME_TimeToDie = TRUE; ERR("Timer still active?!\n");
write(TIME_fdWake[1], &a, sizeof(a)); CloseHandle(TIME_hMMTimer);
}
WaitForSingleObject(TIME_hMMTimer, INFINITE);
close(TIME_fdWake[0]); close(TIME_fdWake[0]);
close(TIME_fdWake[1]); close(TIME_fdWake[1]);
TIME_fdWake[0] = TIME_fdWake[1] = -1;
CloseHandle(TIME_hMMTimer);
TIME_hMMTimer = 0;
DeleteCriticalSection(&TIME_cbcrst); DeleteCriticalSection(&TIME_cbcrst);
} }
} }
...@@ -368,6 +369,8 @@ MMRESULT WINAPI timeKillEvent(UINT wID) ...@@ -368,6 +369,8 @@ MMRESULT WINAPI timeKillEvent(UINT wID)
break; break;
} }
} }
if (list_empty(&timer_list))
TIME_TimeToDie = 1;
LeaveCriticalSection(&WINMM_cs); LeaveCriticalSection(&WINMM_cs);
if (!lpSelf) if (!lpSelf)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment