Merge pull request #615 from nealef/master
[mono.git] / mono / metadata / threadpool.c
index 85ae229e37afba5ba83006b23beeae50dbd2dc92..9a9e7a4cb345ac73cd88bce8d3ed4a273fd8d461 100644 (file)
@@ -29,6 +29,7 @@
 #include <mono/utils/mono-time.h>
 #include <mono/utils/mono-proclib.h>
 #include <mono/utils/mono-semaphore.h>
+#include <mono/utils/atomic.h>
 #include <errno.h>
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
@@ -158,6 +159,7 @@ static MonoClass *process_async_call_klass;
 
 static GPtrArray *wsqs;
 CRITICAL_SECTION wsqs_lock;
+static gboolean suspended;
 
 /* Hooks */
 static MonoThreadPoolFunc tp_start_func;
@@ -515,7 +517,7 @@ socket_io_init (SocketIOData *data)
                data->event_system = POLL_BACKEND;
 
        init_event_system (data);
-       mono_thread_create_internal (mono_get_root_domain (), data->wait, data, TRUE, SMALL_STACK);
+       mono_thread_create_internal (mono_get_root_domain (), data->wait, data, TRUE, FALSE, SMALL_STACK);
        LeaveCriticalSection (&data->io_lock);
        data->inited = 2;
        threadpool_start_thread (&async_io_tp);
@@ -667,7 +669,7 @@ threadpool_start_idle_threads (ThreadPool *tp)
 #ifndef DISABLE_PERFCOUNTERS
                mono_perfcounter_update_value (tp->pc_nthreads, TRUE, 1);
 #endif
-               mono_thread_create_internal (mono_get_root_domain (), tp->async_invoke, tp, TRUE, stack_size);
+               mono_thread_create_internal (mono_get_root_domain (), tp->async_invoke, tp, TRUE, FALSE, stack_size);
                SleepEx (100, TRUE);
        } while (1);
 }
@@ -777,6 +779,9 @@ monitor_thread (gpointer unused)
                if (mono_runtime_is_shutting_down ())
                        break;
 
+               if (suspended)
+                       continue;
+
                for (i = 0; i < 2; i++) {
                        ThreadPool *tp;
                        tp = pools [i];
@@ -1009,7 +1014,7 @@ threadpool_start_thread (ThreadPool *tp)
 #ifndef DISABLE_PERFCOUNTERS
                        mono_perfcounter_update_value (tp->pc_nthreads, TRUE, 1);
 #endif
-                       mono_thread_create_internal (mono_get_root_domain (), tp->async_invoke, tp, TRUE, stack_size);
+                       mono_thread_create_internal (mono_get_root_domain (), tp->async_invoke, tp, TRUE, FALSE, stack_size);
                        return TRUE;
                }
        }
@@ -1048,12 +1053,12 @@ threadpool_append_jobs (ThreadPool *tp, MonoObject **jobs, gint njobs)
 
        if (tp->pool_status == 0 && InterlockedCompareExchange (&tp->pool_status, 1, 0) == 0) {
                if (!tp->is_io) {
-                       mono_thread_create_internal (mono_get_root_domain (), monitor_thread, NULL, TRUE, SMALL_STACK);
+                       mono_thread_create_internal (mono_get_root_domain (), monitor_thread, NULL, TRUE, FALSE, SMALL_STACK);
                        threadpool_start_thread (tp);
                }
                /* Create on demand up to min_threads to avoid startup penalty for apps that don't use
                 * the threadpool that much
-               * mono_thread_create_internal (mono_get_root_domain (), threadpool_start_idle_threads, tp, TRUE, SMALL_STACK);
+               * mono_thread_create_internal (mono_get_root_domain (), threadpool_start_idle_threads, tp, TRUE, FALSE, SMALL_STACK);
                */
        }
 
@@ -1594,9 +1599,9 @@ ves_icall_System_Threading_ThreadPool_SetMinThreads (gint workerThreads, gint co
        InterlockedExchange (&async_tp.min_threads, workerThreads);
        InterlockedExchange (&async_io_tp.min_threads, completionPortThreads);
        if (workerThreads > async_tp.nthreads)
-               mono_thread_create_internal (mono_get_root_domain (), threadpool_start_idle_threads, &async_tp, TRUE, SMALL_STACK);
+               mono_thread_create_internal (mono_get_root_domain (), threadpool_start_idle_threads, &async_tp, TRUE, FALSE, SMALL_STACK);
        if (completionPortThreads > async_io_tp.nthreads)
-               mono_thread_create_internal (mono_get_root_domain (), threadpool_start_idle_threads, &async_io_tp, TRUE, SMALL_STACK);
+               mono_thread_create_internal (mono_get_root_domain (), threadpool_start_idle_threads, &async_io_tp, TRUE, FALSE, SMALL_STACK);
        return TRUE;
 }
 
@@ -1675,3 +1680,21 @@ mono_internal_thread_unhandled_exception (MonoObject* exc)
                 mono_thread_internal_reset_abort (mono_thread_internal_current ());
        }
 }
+
+/*
+ * Suspend creation of new threads.
+ */
+void
+mono_thread_pool_suspend (void)
+{
+       suspended = TRUE;
+}
+
+/*
+ * Resume creation of new threads.
+ */
+void
+mono_thread_pool_resume (void)
+{
+       suspended = FALSE;
+}