On Windows wait indefinitely in dmon thread
Avoid waiting with a finite timeout and wait indefinitely in dmon thread. When we need to unwatch we send a signal to a special event meant to wakeup the waiting thread.
This commit is contained in:
parent
f0aea5b1a4
commit
6584bdfd33
|
@ -409,6 +409,7 @@ typedef struct dmon__state {
|
||||||
volatile LONG modify_watches;
|
volatile LONG modify_watches;
|
||||||
dmon__win32_event* events;
|
dmon__win32_event* events;
|
||||||
bool quit;
|
bool quit;
|
||||||
|
HANDLE wake_event;
|
||||||
} dmon__state;
|
} dmon__state;
|
||||||
|
|
||||||
static bool _dmon_init;
|
static bool _dmon_init;
|
||||||
|
@ -494,7 +495,7 @@ _DMON_PRIVATE void dmon__win32_process_events(void)
|
||||||
_DMON_PRIVATE DWORD WINAPI dmon__thread(LPVOID arg)
|
_DMON_PRIVATE DWORD WINAPI dmon__thread(LPVOID arg)
|
||||||
{
|
{
|
||||||
_DMON_UNUSED(arg);
|
_DMON_UNUSED(arg);
|
||||||
HANDLE wait_handles[DMON_MAX_WATCHES];
|
HANDLE wait_handles[DMON_MAX_WATCHES + 1];
|
||||||
|
|
||||||
SYSTEMTIME starttm;
|
SYSTEMTIME starttm;
|
||||||
GetSystemTime(&starttm);
|
GetSystemTime(&starttm);
|
||||||
|
@ -517,9 +518,12 @@ _DMON_PRIVATE DWORD WINAPI dmon__thread(LPVOID arg)
|
||||||
wait_handles[i] = watch->overlapped.hEvent;
|
wait_handles[i] = watch->overlapped.hEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD wait_result = WaitForMultipleObjects(_dmon.num_watches, wait_handles, FALSE, 10);
|
const int n = _dmon.num_watches;
|
||||||
// FIXME: do not check for WAIT_ABANDONED_<n>, check if that can happen.
|
wait_handles[n] = _dmon.wake_event;
|
||||||
if (wait_result != WAIT_TIMEOUT && wait_result != WAIT_FAILED) {
|
DWORD wait_result = WaitForMultipleObjects(n + 1, wait_handles, FALSE, INFINITE);
|
||||||
|
DMON_ASSERT(wait_result != WAIT_TIMEOUT);
|
||||||
|
// NOTE: maybe we should check for WAIT_ABANDONED_<n> values if that can happen.
|
||||||
|
if (wait_result != WAIT_FAILED && wait_result != WAIT_OBJECT_0 + n) {
|
||||||
dmon__watch_state* watch = &_dmon.watches[wait_result - WAIT_OBJECT_0];
|
dmon__watch_state* watch = &_dmon.watches[wait_result - WAIT_OBJECT_0];
|
||||||
|
|
||||||
DWORD bytes;
|
DWORD bytes;
|
||||||
|
@ -586,6 +590,7 @@ DMON_API_IMPL void dmon_init(void)
|
||||||
|
|
||||||
_dmon.thread_handle =
|
_dmon.thread_handle =
|
||||||
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)dmon__thread, NULL, 0, NULL);
|
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)dmon__thread, NULL, 0, NULL);
|
||||||
|
_dmon.wake_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
DMON_ASSERT(_dmon.thread_handle);
|
DMON_ASSERT(_dmon.thread_handle);
|
||||||
_dmon_init = true;
|
_dmon_init = true;
|
||||||
}
|
}
|
||||||
|
@ -673,6 +678,7 @@ DMON_API_IMPL void dmon_unwatch(dmon_watch_id id)
|
||||||
DMON_ASSERT(id.id > 0);
|
DMON_ASSERT(id.id > 0);
|
||||||
|
|
||||||
_InterlockedExchange(&_dmon.modify_watches, 1);
|
_InterlockedExchange(&_dmon.modify_watches, 1);
|
||||||
|
SetEvent(_dmon.wake_event);
|
||||||
EnterCriticalSection(&_dmon.mutex);
|
EnterCriticalSection(&_dmon.mutex);
|
||||||
|
|
||||||
int index = id.id - 1;
|
int index = id.id - 1;
|
||||||
|
|
Loading…
Reference in New Issue