[threads] Remove mono_threads_create_thread (#4411)
[mono.git] / mono / metadata / threadpool-io.c
index c7986ab0d60dd487d353f3b5cf5a0c1c1a6606d5..4e3b30f011541330aa48beb58265f4b6d68a9d17 100644 (file)
@@ -29,6 +29,7 @@
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/mono-lazy-init.h>
 #include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32api.h>
 
 typedef struct {
        gboolean (*init) (gint wakeup_pipe_fd);
@@ -306,6 +307,12 @@ wait_callback (gint fd, gint events, gpointer user_data)
 }
 
 static void
+selector_thread_interrupt (gpointer unused)
+{
+       selector_thread_wakeup ();
+}
+
+static gsize WINAPI
 selector_thread (gpointer data)
 {
        MonoError error;
@@ -315,14 +322,18 @@ selector_thread (gpointer data)
 
        if (mono_runtime_is_shutting_down ()) {
                io_selector_running = FALSE;
-               return;
+               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");
 
-       for (;;) {
+       while (!mono_runtime_is_shutting_down ()) {
                gint i, j;
                gint res;
+               gboolean interrupted = FALSE;
+
+               if (mono_thread_interruption_checkpoint ())
+                       continue;
 
                mono_coop_mutex_lock (&threadpool_io->updates_lock);
 
@@ -421,15 +432,22 @@ selector_thread (gpointer data)
 
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: wai");
 
-               res = threadpool_io->backend.event_wait (wait_callback, states);
+               mono_thread_info_install_interrupt (selector_thread_interrupt, NULL, &interrupted);
+               if (interrupted)
+                       continue;
 
-               if (res == -1 || mono_runtime_is_shutting_down ())
+               res = threadpool_io->backend.event_wait (wait_callback, states);
+               if (res == -1)
                        break;
+
+               mono_thread_info_uninstall_interrupt (&interrupted);
        }
 
        mono_g_hash_table_destroy (states);
 
        io_selector_running = FALSE;
+
+       return 0;
 }
 
 /* Locking: threadpool_io->updates_lock must be held */
@@ -538,20 +556,14 @@ initialize (void)
                g_error ("initialize: backend->init () failed");
 
        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));
 }
 
 static void
 cleanup (void)
 {
-       /* we make the assumption along the code that we are
-        * cleaning up only if the runtime is shutting down */
-       g_assert (mono_runtime_is_shutting_down ());
-
-       selector_thread_wakeup ();
-       while (io_selector_running)
-               mono_thread_info_usleep (1000);
+       // FIXME destroy everything
 }
 
 void