MonoCoopMutex worker_creation_lock;
gint32 heuristic_completions;
- guint32 heuristic_sample_start;
- guint32 heuristic_last_dequeue; // ms
- guint32 heuristic_last_adjustment; // ms
- guint32 heuristic_adjustment_interval; // ms
+ gint64 heuristic_sample_start;
+ gint64 heuristic_last_dequeue; // ms
+ gint64 heuristic_last_adjustment; // ms
+ gint64 heuristic_adjustment_interval; // ms
ThreadPoolHillClimbing heuristic_hill_climbing;
MonoCoopMutex heuristic_lock;
static gboolean
monitor_sufficient_delay_since_last_dequeue (void)
{
- guint32 threshold;
+ gint64 threshold;
g_assert (threadpool);
mono_gc_set_skip_thread (TRUE);
do {
- guint32 ts;
+ gint64 ts;
gboolean alerted = FALSE;
if (mono_runtime_is_shutting_down ())
}
static gint16
-hill_climbing_update (gint16 current_thread_count, guint32 sample_duration, gint32 completions, guint32 *adjustment_interval)
+hill_climbing_update (gint16 current_thread_count, guint32 sample_duration, gint32 completions, gint64 *adjustment_interval)
{
ThreadPoolHillClimbing *hc;
ThreadPoolHeuristicStateTransition transition;
if (mono_coop_mutex_trylock (&threadpool->heuristic_lock) == 0) {
gint32 completions = InterlockedExchange (&threadpool->heuristic_completions, 0);
- guint32 sample_end = mono_msec_ticks ();
- guint32 sample_duration = sample_end - threadpool->heuristic_sample_start;
+ gint64 sample_end = mono_msec_ticks ();
+ gint64 sample_duration = sample_end - threadpool->heuristic_sample_start;
if (sample_duration >= threadpool->heuristic_adjustment_interval / 2) {
ThreadPoolCounter counter;
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);
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);
}
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);
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;
}
} 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;
mono_threadpool_ms_remove_domain_jobs (MonoDomain *domain, int timeout)
{
gboolean res = TRUE;
- guint32 start;
+ gint64 end;
gpointer sem;
g_assert (domain);
g_assert (mono_domain_is_unloading (domain));
if (timeout != -1)
- start = mono_msec_ticks ();
+ end = mono_msec_ticks () + timeout;
#ifndef DISABLE_SOCKETS
mono_threadpool_ms_io_remove_domain_jobs (domain);
if (timeout != -1) {
- timeout -= mono_msec_ticks () - start;
- if (timeout < 0)
+ if (mono_msec_ticks () > end)
return FALSE;
}
#endif
mono_memory_write_barrier ();
while (domain->threadpool_jobs) {
- MONO_PREPARE_BLOCKING;
- WaitForSingleObject (sem, timeout);
- MONO_FINISH_BLOCKING;
+ gint64 now;
+
if (timeout != -1) {
- timeout -= mono_msec_ticks () - start;
- if (timeout <= 0) {
+ now = mono_msec_ticks ();
+ if (now > end) {
res = FALSE;
break;
}
}
+
+ MONO_ENTER_GC_SAFE;
+ WaitForSingleObject (sem, timeout != -1 ? end - now : timeout);
+ MONO_EXIT_GC_SAFE;
}
domain->cleanup_semaphore = NULL;