X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fthreadpool.c;h=a7f7c04f54e6d4a87223171e98f49bbf6ab60c23;hb=dc1155ddcf876d543da9a162a69e14d4903d2ac8;hp=9dd19c067ec486c7269565ac56ebaa2394f45c35;hpb=c4aef31eeea309e6a795c84c098ac8e1a2490340;p=mono.git diff --git a/mono/metadata/threadpool.c b/mono/metadata/threadpool.c index 9dd19c067ec..a7f7c04f54e 100644 --- a/mono/metadata/threadpool.c +++ b/mono/metadata/threadpool.c @@ -95,14 +95,17 @@ static SocketIOData socket_io_data; static HANDLE job_added; static HANDLE io_job_added; +/* Keep in sync with the System.MonoAsyncCall class which provides GC tracking */ typedef struct { + MonoObject object; MonoMethodMessage *msg; - HANDLE wait_event; MonoMethod *cb_method; MonoDelegate *cb_target; MonoObject *state; MonoObject *res; MonoArray *out_args; + /* This is a HANDLE, we use guint64 so the managed object layout remains constant */ + guint64 wait_event; } ASyncCall; static void async_invoke_thread (gpointer data); @@ -114,6 +117,7 @@ static gpointer dequeue_job (CRITICAL_SECTION *cs, GList **plist); static GList *async_call_queue = NULL; static GList *async_io_queue = NULL; +static MonoClass *async_call_klass; static MonoClass *socket_async_call_klass; #define INIT_POLLFD(a, b, c) {(a)->fd = b; (a)->events = c; (a)->revents = 0;} @@ -245,7 +249,7 @@ async_invoke_io_thread (gpointer data) ASyncCall *ac; mono_async_invoke (ar); - ac = (ASyncCall *) ar->data; + ac = (ASyncCall *) ar->object_data; /* if (ac->msg->exc != NULL) mono_unhandled_exception (ac->msg->exc); @@ -764,8 +768,9 @@ socket_io_add_poll (MonoSocketAsyncResult *state) GSList *list; SocketIOData *data = &socket_io_data; -#ifdef PLATFORM_MACOSX +#if defined(PLATFORM_MACOSX) || defined(PLATFORM_BSD6) /* select() for connect() does not work well on the Mac. Bug #75436. */ + /* Bug #77637 for the BSD 6 case */ if (state->operation == AIO_OP_CONNECT && state->blocking == TRUE) { start_io_thread_or_queue (state); return; @@ -849,7 +854,7 @@ static void socket_io_add (MonoAsyncResult *ares, MonoSocketAsyncResult *state) { socket_io_init (&socket_io_data); - state->ares = ares; + MONO_OBJECT_SETREF (state, ares, ares); #ifdef HAVE_EPOLL if (socket_io_data.epoll_disabled == FALSE) { if (socket_io_add_epoll (state)) @@ -896,14 +901,14 @@ socket_io_filter (MonoObject *target, MonoObject *state) static void mono_async_invoke (MonoAsyncResult *ares) { - ASyncCall *ac = (ASyncCall *)ares->data; + ASyncCall *ac = (ASyncCall *)ares->object_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; + MONO_OBJECT_SETREF (ares, original_context, thread->execution_context); + MONO_OBJECT_SETREF (thread, execution_context, ares->execution_context); } else { ares->original_context = NULL; } @@ -922,12 +927,12 @@ mono_async_invoke (MonoAsyncResult *ares) /* '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; + MONO_OBJECT_SETREF (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; + MONO_OBJECT_SETREF (thread, execution_context, ares->original_context); ares->original_context = NULL; } @@ -956,7 +961,7 @@ mono_thread_pool_init () MONO_GC_REGISTER_ROOT (ares_htable); InitializeCriticalSection (&socket_io_data.io_lock); InitializeCriticalSection (&ares_lock); - ares_htable = mono_g_hash_table_new (NULL, NULL); + ares_htable = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_VALUE_GC); job_added = CreateSemaphore (NULL, 0, 0x7fffffff, NULL); GetSystemInfo (&info); if (g_getenv ("MONO_THREADS_PER_CPU") != NULL) { @@ -966,6 +971,9 @@ mono_thread_pool_init () } mono_max_worker_threads = 20 + threads_per_cpu * info.dwNumberOfProcessors; + + async_call_klass = mono_class_from_name (mono_defaults.corlib, "System", "MonoAsyncCall"); + g_assert (async_call_klass); } MonoAsyncResult * @@ -978,21 +986,23 @@ mono_thread_pool_add (MonoObject *target, MonoMethodMessage *msg, MonoDelegate * #ifdef HAVE_BOEHM_GC ac = GC_MALLOC (sizeof (ASyncCall)); +#elif defined(HAVE_SGEN_GC) + ac = mono_object_new (mono_domain_get (), async_call_klass); #else /* We'll leak the event if creaated... */ ac = g_new0 (ASyncCall, 1); #endif ac->wait_event = NULL; - ac->msg = msg; - ac->state = state; + MONO_OBJECT_SETREF (ac, msg, msg); + MONO_OBJECT_SETREF (ac, state, state); if (async_callback) { ac->cb_method = mono_get_delegate_invoke (((MonoObject *)async_callback)->vtable->klass); ac->cb_target = async_callback; } - ares = mono_async_result_new (domain, NULL, ac->state, ac); - ares->async_delegate = target; + ares = mono_async_result_new (domain, NULL, ac->state, NULL, ac); + MONO_OBJECT_SETREF (ares, async_delegate, target); EnterCriticalSection (&ares_lock); mono_g_hash_table_insert (ares_htable, ares, ares); @@ -1046,7 +1056,7 @@ mono_thread_pool_finish (MonoAsyncResult *ares, MonoArray **out_args, MonoObject } ares->endinvoke_called = 1; - ac = (ASyncCall *)ares->data; + ac = (ASyncCall *)ares->object_data; g_assert (ac != NULL); @@ -1054,7 +1064,7 @@ mono_thread_pool_finish (MonoAsyncResult *ares, MonoArray **out_args, MonoObject if (!ares->completed) { if (ares->handle == NULL) { ac->wait_event = CreateEvent (NULL, TRUE, FALSE, NULL); - ares->handle = (MonoObject *) mono_wait_handle_new (mono_object_domain (ares), ac->wait_event); + MONO_OBJECT_SETREF (ares, handle, (MonoObject *) mono_wait_handle_new (mono_object_domain (ares), ac->wait_event)); } mono_monitor_exit ((MonoObject *) ares); WaitForSingleObjectEx (ac->wait_event, INFINITE, TRUE); @@ -1062,7 +1072,7 @@ mono_thread_pool_finish (MonoAsyncResult *ares, MonoArray **out_args, MonoObject mono_monitor_exit ((MonoObject *) ares); } - *exc = ac->msg->exc; + *exc = ac->msg->exc; /* FIXME: GC add write barrier */ *out_args = ac->out_args; return ac->res; @@ -1156,7 +1166,7 @@ async_invoke_thread (gpointer data) ASyncCall *ac; mono_async_invoke (ar); - ac = (ASyncCall *) ar->data; + ac = (ASyncCall *) ar->object_data; /* if (ac->msg->exc != NULL) mono_unhandled_exception (ac->msg->exc);