From 41d647d2524c393058c5175ee9487506ae4ed957 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Thu, 23 Mar 2017 10:09:33 -0400 Subject: [PATCH] [threadpool-io] Ensure selector thread is running before waiting on it (#4572) This could result in a unecessary wait on shutdown where the selector thread would have exited, and the finalizer thread would try to dispose a Socket, which would try to remove the socket from the IOSelector. This removal operation would wait on the selector thread to acknowledge the removal, but because the selector thread would have alreday exited, we would wait on an event that would never happen. --- mono/metadata/threadpool-io.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/mono/metadata/threadpool-io.c b/mono/metadata/threadpool-io.c index 4e3b30f0115..5048c6ae08f 100644 --- a/mono/metadata/threadpool-io.c +++ b/mono/metadata/threadpool-io.c @@ -318,8 +318,6 @@ selector_thread (gpointer data) MonoError error; MonoGHashTable *states; - io_selector_running = TRUE; - if (mono_runtime_is_shutting_down ()) { io_selector_running = FALSE; return 0; @@ -445,7 +443,12 @@ selector_thread (gpointer data) mono_g_hash_table_destroy (states); + mono_coop_mutex_lock (&threadpool_io->updates_lock); + io_selector_running = FALSE; + mono_coop_cond_broadcast (&threadpool_io->updates_cond); + + mono_coop_mutex_unlock (&threadpool_io->updates_lock); return 0; } @@ -555,9 +558,15 @@ initialize (void) if (!threadpool_io->backend.init (threadpool_io->wakeup_pipes [0])) g_error ("initialize: backend->init () failed"); + mono_coop_mutex_lock (&threadpool_io->updates_lock); + + io_selector_running = TRUE; + MonoError error; if (!mono_thread_create_internal (mono_get_root_domain (), selector_thread, NULL, MONO_THREAD_CREATE_FLAGS_THREADPOOL | MONO_THREAD_CREATE_FLAGS_SMALL_STACK, &error)) g_error ("initialize: mono_thread_create_internal () failed due to %s", mono_error_get_message (&error)); + + mono_coop_mutex_unlock (&threadpool_io->updates_lock); } static void @@ -591,6 +600,11 @@ ves_icall_System_IOSelector_Add (gpointer handle, MonoIOSelectorJob *job) mono_coop_mutex_lock (&threadpool_io->updates_lock); + if (!io_selector_running) { + mono_coop_mutex_unlock (&threadpool_io->updates_lock); + return; + } + update = update_get_new (); update->type = UPDATE_ADD; update->data.add.fd = GPOINTER_TO_INT (handle); @@ -618,6 +632,11 @@ mono_threadpool_io_remove_socket (int fd) mono_coop_mutex_lock (&threadpool_io->updates_lock); + if (!io_selector_running) { + mono_coop_mutex_unlock (&threadpool_io->updates_lock); + return; + } + update = update_get_new (); update->type = UPDATE_REMOVE_SOCKET; update->data.add.fd = fd; @@ -640,6 +659,11 @@ mono_threadpool_io_remove_domain_jobs (MonoDomain *domain) mono_coop_mutex_lock (&threadpool_io->updates_lock); + if (!io_selector_running) { + mono_coop_mutex_unlock (&threadpool_io->updates_lock); + return; + } + update = update_get_new (); update->type = UPDATE_REMOVE_DOMAIN; update->data.remove_domain.domain = domain; -- 2.25.1