From: Ludovic Henry Date: Thu, 23 Mar 2017 14:09:33 +0000 (-0400) Subject: [threadpool-io] Ensure selector thread is running before waiting on it (#4572) X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mono.git;a=commitdiff_plain;h=41d647d2524c393058c5175ee9487506ae4ed957 [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. --- 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;