Merge pull request #3028 from lateralusX/jlorenss/threadpool_warning
[mono.git] / mono / metadata / threadpool-ms.c
index 69ade32e593ef5fc5db50665d5924f1069595dcb..1f4a6cc605237a36e6f13c3a28acc3c229086dff 100644 (file)
@@ -708,13 +708,15 @@ worker_try_create (void)
 {
        ThreadPoolCounter counter;
        MonoInternalThread *thread;
+       gint64 current_ticks;
        gint32 now;
 
        mono_coop_mutex_lock (&threadpool->worker_creation_lock);
 
        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_THREADPOOL, "[%p] try create worker", mono_native_thread_id_get ());
-
-       if ((now = mono_100ns_ticks () / 10 / 1000 / 1000) == 0) {
+       current_ticks = mono_100ns_ticks ();
+       now = current_ticks / (10 * 1000 * 1000);
+       if (0 == current_ticks) {
                g_warning ("failed to get 100ns ticks");
        } else {
                if (threadpool->worker_creation_current_second != now) {
@@ -1341,7 +1343,8 @@ mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMet
 
        mono_error_init (error);
 
-       message = mono_method_call_message_new (method, params, mono_get_delegate_invoke (method->klass), (params != NULL) ? (&async_callback) : NULL, (params != NULL) ? (&state) : NULL);
+       message = mono_method_call_message_new (method, params, mono_get_delegate_invoke (method->klass), (params != NULL) ? (&async_callback) : NULL, (params != NULL) ? (&state) : NULL, error);
+       return_val_if_nok (error, NULL);
 
        async_call = (MonoAsyncCall*) mono_object_new_checked (domain, async_call_klass, error);
        return_val_if_nok (error, NULL);
@@ -1354,7 +1357,8 @@ mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMet
                MONO_OBJECT_SETREF (async_call, cb_target, async_callback);
        }
 
-       async_result = mono_async_result_new (domain, NULL, async_call->state, NULL, (MonoObject*) async_call);
+       async_result = mono_async_result_new (domain, NULL, async_call->state, NULL, (MonoObject*) async_call, error);
+       return_val_if_nok (error, NULL);
        MONO_OBJECT_SETREF (async_result, async_delegate, target);
 
        mono_threadpool_ms_enqueue_work_item (domain, (MonoObject*) async_result, error);
@@ -1364,11 +1368,11 @@ mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMet
 }
 
 MonoObject *
-mono_threadpool_ms_end_invoke (MonoAsyncResult *ares, MonoArray **out_args, MonoObject **exc)
+mono_threadpool_ms_end_invoke (MonoAsyncResult *ares, MonoArray **out_args, MonoObject **exc, MonoError *error)
 {
-       MonoError error;
        MonoAsyncCall *ac;
 
+       mono_error_init (error);
        g_assert (exc);
        g_assert (out_args);
 
@@ -1379,7 +1383,7 @@ mono_threadpool_ms_end_invoke (MonoAsyncResult *ares, MonoArray **out_args, Mono
        mono_monitor_enter ((MonoObject*) ares);
 
        if (ares->endinvoke_called) {
-               *exc = (MonoObject*) mono_get_exception_invalid_operation (NULL);
+               mono_error_set_invalid_operation(error, "Delegate EndInvoke method called more than once");
                mono_monitor_exit ((MonoObject*) ares);
                return NULL;
        }
@@ -1396,14 +1400,17 @@ mono_threadpool_ms_end_invoke (MonoAsyncResult *ares, MonoArray **out_args, Mono
                } else {
                        wait_event = CreateEvent (NULL, TRUE, FALSE, NULL);
                        g_assert(wait_event);
-                       MonoWaitHandle *wait_handle = mono_wait_handle_new (mono_object_domain (ares), wait_event, &error);
-                       mono_error_raise_exception (&error); /* FIXME don't raise here */
+                       MonoWaitHandle *wait_handle = mono_wait_handle_new (mono_object_domain (ares), wait_event, error);
+                       if (!is_ok (error)) {
+                               CloseHandle (wait_event);
+                               return NULL;
+                       }
                        MONO_OBJECT_SETREF (ares, handle, (MonoObject*) wait_handle);
                }
                mono_monitor_exit ((MonoObject*) ares);
-               MONO_PREPARE_BLOCKING;
+               MONO_ENTER_GC_SAFE;
                WaitForSingleObjectEx (wait_event, INFINITE, TRUE);
-               MONO_FINISH_BLOCKING;
+               MONO_EXIT_GC_SAFE;
        }
 
        ac = (MonoAsyncCall*) ares->object_data;
@@ -1461,9 +1468,9 @@ mono_threadpool_ms_remove_domain_jobs (MonoDomain *domain, int timeout)
                        }
                }
 
-               MONO_PREPARE_BLOCKING;
+               MONO_ENTER_GC_SAFE;
                WaitForSingleObject (sem, timeout != -1 ? end - now : timeout);
-               MONO_FINISH_BLOCKING;
+               MONO_EXIT_GC_SAFE;
        }
 
        domain->cleanup_semaphore = NULL;