Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / metadata / threadpool-io.c
index 618d995dceb7db96eccc7cccbdc98e1852f4cd56..a40ed6de5ea1e62c8c98d1082d18b5f3b919b365 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * threadpool-io.c: Microsoft IO threadpool runtime support
+/**
+ * \file
+ * Microsoft IO threadpool runtime support
  *
  * Author:
  *     Ludovic Henry (ludovic.henry@xamarin.com)
@@ -318,14 +319,12 @@ selector_thread (gpointer data)
        MonoError error;
        MonoGHashTable *states;
 
-       io_selector_running = TRUE;
-
        if (mono_runtime_is_shutting_down ()) {
                io_selector_running = FALSE;
                return 0;
        }
 
-       states = mono_g_hash_table_new_type (g_direct_hash, g_direct_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_THREAD_POOL, "i/o thread pool states table");
+       states = mono_g_hash_table_new_type (g_direct_hash, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_THREAD_POOL, "i/o thread pool states table");
 
        while (!mono_runtime_is_shutting_down ()) {
                gint i, j;
@@ -445,7 +444,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;
 }
@@ -542,7 +546,7 @@ initialize (void)
        threadpool_io->updates_size = 0;
 
        threadpool_io->backend = backend_poll;
-       if (g_getenv ("MONO_ENABLE_AIO") != NULL) {
+       if (g_hasenv ("MONO_ENABLE_AIO")) {
 #if defined(HAVE_EPOLL)
                threadpool_io->backend = backend_epoll;
 #elif defined(HAVE_KQUEUE)
@@ -555,9 +559,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, TRUE, SMALL_STACK, &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 +601,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 +633,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 +660,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;