#ifdef PLATFORM_WIN32
#define WINVER 0x0500
#define _WIN32_WINNT 0x0500
-#define THREADS_PER_CPU 25
-#else
-#define THREADS_PER_CPU 50
#endif
+#define THREADS_PER_CPU 5 /* 20 + THREADS_PER_CPU * number of CPUs */
+
#include <mono/metadata/domain-internals.h>
#include <mono/metadata/tabledefs.h>
#include <mono/metadata/threads.h>
#undef EPOLL_DEBUG
/* maximum number of worker threads */
-static int mono_max_worker_threads = THREADS_PER_CPU;
-static int mono_min_worker_threads = 0;
-static int mono_io_max_worker_threads = THREADS_PER_CPU * 2;
+static int mono_max_worker_threads;
+static int mono_min_worker_threads;
+static int mono_io_max_worker_threads;
/* current number of worker threads */
static int mono_worker_threads = 0;
MonoThread *thread;
thread = mono_thread_current ();
thread->threadpool_thread = TRUE;
- thread->state |= ThreadState_Background;
+ ves_icall_System_Threading_Thread_SetState (thread, ThreadState_Background);
for (;;) {
MonoSocketAsyncResult *state;
}
domain = ((MonoObject *)ar)->vtable->domain;
+ mono_thread_push_appdomain_ref (domain);
if (mono_domain_set (domain, FALSE)) {
ASyncCall *ac;
- mono_thread_push_appdomain_ref (domain);
mono_async_invoke (ar);
ac = (ASyncCall *) ar->data;
+ /*
if (ac->msg->exc != NULL)
mono_unhandled_exception (ac->msg->exc);
- mono_thread_pop_appdomain_ref ();
+ */
+ mono_domain_set (mono_get_root_domain (), TRUE);
}
+ mono_thread_pop_appdomain_ref ();
InterlockedDecrement (&busy_io_worker_threads);
}
InterlockedIncrement (&busy_io_worker_threads);
InterlockedIncrement (&io_worker_threads);
domain = ((ares) ? ((MonoObject *) ares)->vtable->domain : mono_domain_get ());
- mono_thread_create (domain, async_invoke_io_thread, ares);
+ mono_thread_create (mono_get_root_domain (), async_invoke_io_thread, ares);
} else {
append_job (&io_queue_lock, &async_io_queue, ares);
ReleaseSemaphore (io_job_added, 1, NULL);
thread = mono_thread_current ();
thread->threadpool_thread = TRUE;
- thread->state |= ThreadState_Background;
+ ves_icall_System_Threading_Thread_SetState (thread, ThreadState_Background);
allocated = INITIAL_POLLFD_SIZE;
pfds = g_new0 (mono_pollfd, allocated);
epollfd = data->epollfd;
thread = mono_thread_current ();
thread->threadpool_thread = TRUE;
- thread->state |= ThreadState_Background;
+ ves_icall_System_Threading_Thread_SetState (thread, ThreadState_Background);
events = g_new0 (struct epoll_event, nevents);
while (1) {
g_assert (data->pipe [0] != INVALID_SOCKET);
closesocket (srv);
#endif
+ mono_io_max_worker_threads = mono_max_worker_threads / 2;
+ if (mono_io_max_worker_threads < 10)
+ mono_io_max_worker_threads = 10;
data->sock_to_state = g_hash_table_new (g_direct_hash, g_direct_equal);
mono_async_invoke (MonoAsyncResult *ares)
{
ASyncCall *ac = (ASyncCall *)ares->data;
+ MonoThread *thread = NULL;
+
+ if (ares->execution_context) {
+ /* use captured ExecutionContext (if available) */
+ thread = mono_thread_current ();
+ ares->original_context = thread->execution_context;
+ thread->execution_context = ares->execution_context;
+ } else {
+ ares->original_context = NULL;
+ }
ac->msg->exc = NULL;
ac->res = mono_message_invoke (ares->async_delegate, ac->msg,
MonoObject *exc = NULL;
void *pa = &ares;
mono_runtime_invoke (ac->cb_method, ac->cb_target, pa, &exc);
- if (!ac->msg->exc)
- ac->msg->exc = exc;
+ /* 'exc' will be the previous ac->msg->exc if not NULL and not
+ * catched. If catched, this will be set to NULL and the
+ * exception will not be printed. */
+ ac->msg->exc = exc;
+ }
+
+ /* restore original thread execution context if flow isn't suppressed, i.e. non null */
+ if (ares->original_context) {
+ thread->execution_context = ares->original_context;
+ ares->original_context = NULL;
}
/* notify listeners */
ares_htable = mono_g_hash_table_new (NULL, NULL);
job_added = CreateSemaphore (NULL, 0, 0x7fffffff, NULL);
GetSystemInfo (&info);
- if (getenv ("MONO_THREADS_PER_CPU") != NULL) {
- threads_per_cpu = atoi (getenv ("MONO_THREADS_PER_CPU"));
+ if (g_getenv ("MONO_THREADS_PER_CPU") != NULL) {
+ threads_per_cpu = atoi (g_getenv ("MONO_THREADS_PER_CPU"));
if (threads_per_cpu <= 0)
threads_per_cpu = THREADS_PER_CPU;
}
- mono_max_worker_threads = threads_per_cpu * info.dwNumberOfProcessors;
+ mono_max_worker_threads = 20 + threads_per_cpu * info.dwNumberOfProcessors;
}
MonoAsyncResult *
InterlockedIncrement (&mono_worker_threads);
InterlockedIncrement (&busy_worker_threads);
domain = ((MonoObject *) ares)->vtable->domain;
- mono_thread_create (domain, async_invoke_thread, ares);
+ mono_thread_create (mono_get_root_domain (), async_invoke_thread, ares);
} else {
append_job (&mono_delegate_section, &async_call_queue, ares);
ReleaseSemaphore (job_added, 1, NULL);
thread = mono_thread_current ();
thread->threadpool_thread = TRUE;
- thread->state |= ThreadState_Background;
+ ves_icall_System_Threading_Thread_SetState (thread, ThreadState_Background);
for (;;) {
MonoAsyncResult *ar;
/* worker threads invokes methods in different domains,
* so we need to set the right domain here */
domain = ((MonoObject *)ar)->vtable->domain;
+ mono_thread_push_appdomain_ref (domain);
if (mono_domain_set (domain, FALSE)) {
ASyncCall *ac;
- mono_thread_push_appdomain_ref (domain);
mono_async_invoke (ar);
ac = (ASyncCall *) ar->data;
+ /*
if (ac->msg->exc != NULL)
mono_unhandled_exception (ac->msg->exc);
- mono_thread_pop_appdomain_ref ();
+ */
+ mono_domain_set (mono_get_root_domain (), TRUE);
}
+ mono_thread_pop_appdomain_ref ();
InterlockedDecrement (&busy_worker_threads);
}
data = dequeue_job (&mono_delegate_section, &async_call_queue);
-
+
if (!data) {
guint32 wr;
int timeout = 10000;