Merge branch 'thread-win32-inherit-prio' into 'master'

GThread - Inherit parent thread priority by default for new Win32 threads

See merge request GNOME/glib!1301
This commit is contained in:
Sebastian Dröge 2020-01-15 14:19:36 +00:00
commit 6f34e84002
2 changed files with 57 additions and 7 deletions

View File

@ -439,9 +439,13 @@ g_system_thread_new (GThreadFunc proxy,
GThreadWin32 *thread;
GRealThread *base_thread;
guint ignore;
const gchar *message = NULL;
HANDLE current_thread;
int current_prio;
thread = g_slice_new0 (GThreadWin32);
thread->proxy = proxy;
thread->handle = (HANDLE) NULL;
base_thread = (GRealThread*)thread;
base_thread->ref_count = 2;
base_thread->ours = TRUE;
@ -450,19 +454,57 @@ g_system_thread_new (GThreadFunc proxy,
base_thread->thread.data = data;
base_thread->name = g_strdup (name);
thread->handle = (HANDLE) _beginthreadex (NULL, stack_size, g_thread_win32_proxy, thread, 0, &ignore);
thread->handle = (HANDLE) _beginthreadex (NULL, stack_size, g_thread_win32_proxy, thread,
CREATE_SUSPENDED, &ignore);
if (thread->handle == NULL)
{
gchar *win_error = g_win32_error_message (GetLastError ());
g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN,
"Error creating thread: %s", win_error);
g_free (win_error);
g_slice_free (GThreadWin32, thread);
return NULL;
message = "Error creating thread";
goto error;
}
/* For thread priority inheritance we need to manually set the thread
* priority of the new thread to the priority of the current thread. We
* also have to start the thread suspended and resume it after actually
* setting the priority here.
*
* On Windows, by default all new threads are created with NORMAL thread
* priority.
*/
current_thread = GetCurrentThread ();
current_prio = GetThreadPriority (current_thread);
if (current_prio == THREAD_PRIORITY_ERROR_RETURN)
{
message = "Error getting current thread priority";
goto error;
}
if (SetThreadPriority (thread->handle, current_prio) == 0)
{
message = "Error setting new thread priority";
goto error;
}
if (ResumeThread (thread->handle) == -1)
{
message = "Error resuming new thread";
goto error;
}
return (GRealThread *) thread;
error:
{
gchar *win_error = g_win32_error_message (GetLastError ());
g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN,
"%s: %s", message, win_error);
g_free (win_error);
if (thread->handle)
CloseHandle (thread->handle);
g_slice_free (GThreadWin32, thread);
return NULL;
}
}
void

View File

@ -833,6 +833,14 @@ g_thread_proxy (gpointer data)
* To free the struct returned by this function, use g_thread_unref().
* Note that g_thread_join() implicitly unrefs the #GThread as well.
*
* New threads by default inherit their scheduler policy (POSIX) or thread
* priority (Windows) of the thread creating the new thread.
*
* This behaviour changed in GLib 2.64: before threads on Windows were not
* inheriting the thread priority but were spawned with the default priority.
* Starting with GLib 2.64 the behaviour is now consistent between Windows and
* POSIX and all threads inherit their parent thread's priority.
*
* Returns: the new #GThread
*
* Since: 2.32