#define _WIN32_WINNT 0x0500
#endif
-#include <mono/metadata/appdomain.h>
+#include <mono/metadata/domain-internals.h>
#include <mono/metadata/tabledefs.h>
#include <mono/metadata/threads.h>
+#include <mono/metadata/threads-types.h>
#include <mono/metadata/exception.h>
#include <mono/metadata/file-io.h>
#include <mono/metadata/monitor.h>
/* maximum number of worker threads */
int mono_max_worker_threads = 25; /* fixme: should be 25 per available CPU */
-int mono_min_worker_threads = 0;
+static int mono_min_worker_threads = 0;
/* current number of worker threads */
static int mono_worker_threads = 0;
/* current number of busy threads */
-int busy_worker_threads = 0;
+static int busy_worker_threads = 0;
/* we use this to store a reference to the AsyncResult to avoid GC */
static MonoGHashTable *ares_htable = NULL;
}
/* notify listeners */
- mono_monitor_try_enter ((MonoObject *) ares, INFINITE);
+ if(!mono_monitor_enter ((MonoObject *) ares))
+ return;
+
if (ares->handle != NULL) {
ac->wait_event = ((MonoWaitHandle *) ares->handle)->handle;
SetEvent (ac->wait_event);
ares->async_delegate = target;
if (!ares_htable) {
+ MONO_GC_REGISTER_ROOT (ares_htable);
ares_htable = mono_g_hash_table_new (NULL, NULL);
job_added = CreateSemaphore (NULL, 0, 0x7fffffff, NULL);
}
*out_args = NULL;
/* check if already finished */
- mono_monitor_try_enter ((MonoObject *) ares, INFINITE);
+ if (!mono_monitor_enter ((MonoObject *) ares)) {
+ return NULL;
+ }
+
if (ares->endinvoke_called) {
*exc = (MonoObject *)mono_exception_from_name (mono_defaults.corlib, "System",
"InvalidOperationException");
ares->handle = (MonoObject *) mono_wait_handle_new (mono_object_domain (ares), ac->wait_event);
}
mono_monitor_exit ((MonoObject *) ares);
- WaitForSingleObject (ac->wait_event, INFINITE);
+ WaitForSingleObjectEx (ac->wait_event, INFINITE, TRUE);
} else {
mono_monitor_exit ((MonoObject *) ares);
}
data = dequeue_job ();
- if (!data && WaitForSingleObject (job_added, 500) != WAIT_TIMEOUT)
- data = dequeue_job ();
+ if (!data) {
+ guint32 wr;
+ int timeout = 500;
+ guint32 start_time = GetTickCount ();
+
+ do {
+ wr = WaitForSingleObjectEx (job_added, (guint32)timeout, TRUE);
+ mono_thread_interruption_checkpoint ();
+
+ timeout -= GetTickCount () - start_time;
+
+ if (wr != WAIT_TIMEOUT)
+ data = dequeue_job ();
+ }
+ while (!data && timeout > 0);
+ }
if (!data) {
workers = (int) InterlockedCompareExchange (&mono_worker_threads, 0, -1);
min = (int) InterlockedCompareExchange (&mono_min_worker_threads, 0, -1);
while (!data && workers <= min) {
- WaitForSingleObject (job_added, INFINITE);
+ WaitForSingleObjectEx (job_added, INFINITE, TRUE);
+ mono_thread_interruption_checkpoint ();
+
data = dequeue_job ();
workers = (int) InterlockedCompareExchange (&mono_worker_threads, 0, -1);
min = (int) InterlockedCompareExchange (&mono_min_worker_threads, 0, -1);
*completionPortThreads = 0;
}
-void
+MonoBoolean
ves_icall_System_Threading_ThreadPool_SetMinThreads (gint workerThreads, gint completionPortThreads)
{
MONO_ARCH_SAVE_REGS;
+ if (workerThreads < 0 || workerThreads > mono_max_worker_threads)
+ return FALSE;
InterlockedExchange (&mono_min_worker_threads, workerThreads);
+ /* FIXME: should actually start the idle threads if needed */
+ return TRUE;
}
static void