2006-04-24 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / metadata / threadpool.c
index 4f01b55257e7e53a1b8b1da29102cc10eaf5e9f0..2363ed0dec87f26fbd8d8f3b8f24149533f8d623 100644 (file)
@@ -240,16 +240,19 @@ async_invoke_io_thread (gpointer data)
                        }
 
                        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);
                }
 
@@ -303,7 +306,7 @@ start_io_thread_or_queue (MonoSocketAsyncResult *ares)
                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);
@@ -351,7 +354,7 @@ mark_bad_fds (mono_pollfd *pfds, int nfds)
                if (pfd->fd == -1)
                        continue;
 
-               ret = mono_poll (pfds, 1, 0);
+               ret = mono_poll (pfd, 1, 0);
                if (ret == -1 && errno == EBADF) {
                        pfd->revents |= MONO_POLLNVAL;
                        count++;
@@ -761,6 +764,14 @@ socket_io_add_poll (MonoSocketAsyncResult *state)
        GSList *list;
        SocketIOData *data = &socket_io_data;
 
+#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;
+       }
+#endif
        WaitForSingleObject (data->new_sem, INFINITE);
        if (data->newpfd == NULL)
                data->newpfd = g_new0 (mono_pollfd, 1);
@@ -839,7 +850,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))
@@ -892,8 +903,8 @@ mono_async_invoke (MonoAsyncResult *ares)
        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;
        }
@@ -909,13 +920,15 @@ mono_async_invoke (MonoAsyncResult *ares)
                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. */
+               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;
        }
 
@@ -980,7 +993,7 @@ mono_thread_pool_add (MonoObject *target, MonoMethodMessage *msg, MonoDelegate *
        }
 
        ares = mono_async_result_new (domain, NULL, ac->state, ac);
-       ares->async_delegate = target;
+       MONO_OBJECT_SETREF (ares, async_delegate, target);
 
        EnterCriticalSection (&ares_lock);
        mono_g_hash_table_insert (ares_htable, ares, ares);
@@ -1008,7 +1021,7 @@ start_thread_or_queue (MonoAsyncResult *ares)
                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);
@@ -1042,7 +1055,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);
@@ -1050,7 +1063,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;
@@ -1139,21 +1152,24 @@ async_invoke_thread (gpointer data)
                        /* 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;