Add a GSource for Win32 Event synchronization objects
I propose to add a GSource for Win32 Event synchronization objects
Explanation:
To monitor resources on Windows, many times you get an event HANDLE. Most people then spawn a dedicated thread to wait on such HANDLE, but that does not scale, because as the number of resources to monitor grows up we have to spawn more and more threads.
An alternative is to spawn a single dedicated thread for waits, where event objects can be added dynamically:
/*
* MT-safe
*/
GMutex mutex;
GArray *events;
gboolean
add_event_to_wait_list (HANDLE event)
{
gboolean return_val = FALSE;
g_mutex_lock (&mutex);
if (events->len < G_NUM_ELEMENTS (events))
{
g_array_append_val (events, event);
SetEvent (g_array_index (events, HANDLE, 0));
return_val = TRUE;
}
g_mutex_unlock (&mutex);
return return_val;
}
while (true)
{
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
DWORD handles_count = 1;
g_mutex_lock (&mutex);
handles_count = events->len;
memcpy (handles, events->data, handles_count * sizeof (HANDLE));
g_mutex_unlock (&mutex);
DWORD ret = WaitForMultipleObjects (handles_count, handles, FALSE, INFINITE);
if (ret == WAIT_OBJECT_0)
{
/* Special event that signals when we have to recreate the list
* of HANDLEs and then go to wait again, as an HANDLE has to be
* added or removed */
}
else if (ret > WAIT_OBJECT_0 && ret < WAIT_OBJECT_0 + handles_count)
{
/* One of the events has been signaled, schedule a GCallback on
* the GMainContext using an idle source */
}
else if (ret == WAIT_FAILED)
{
g_error ("WaitForMultipleObjects failed with error code %u",
(unsigned int) GetLastError ());
}
}
Most of that is already implemented by the Thread Pool Apis: see e.g SetThreadpoolWait, which supersedes the older RegisterWaitForSingleObject.
Anyway, spawning a thread to wait and then schedule an idle callback is no better than waiting directly in gpoll () using an appropriate GSource.
That GSource could be useful for:
- Detecting registry changes (needed for GtkSettings on Windows)
- Have a proper V-Sync source on Windows (needed for GdkFrameClock)
- Etc.