typedef struct DomainFinalizationReq {
MonoDomain *domain;
-#ifdef TARGET_WIN32
- HANDLE done_event;
-#else
- gboolean done;
- MonoCoopCond cond;
- MonoCoopMutex mutex;
-#endif
+ MonoCoopSem done;
} DomainFinalizationReq;
static gboolean gc_disabled = FALSE;
return result;
}
-typedef struct {
- MonoCoopCond *cond;
- MonoCoopMutex *mutex;
-} BreakCoopAlertableWaitUD;
-
-static inline void
-break_coop_alertable_wait (gpointer user_data)
-{
- BreakCoopAlertableWaitUD *ud = (BreakCoopAlertableWaitUD*)user_data;
-
- mono_coop_mutex_lock (ud->mutex);
- mono_coop_cond_signal (ud->cond);
- mono_coop_mutex_unlock (ud->mutex);
-}
-
-/*
- * coop_cond_timedwait_alertable:
- *
- * Wait on COND/MUTEX. If ALERTABLE is non-null, the wait can be interrupted.
- * In that case, *ALERTABLE will be set to TRUE, and 0 is returned.
- */
-static inline gint
-coop_cond_timedwait_alertable (MonoCoopCond *cond, MonoCoopMutex *mutex, guint32 timeout_ms, gboolean *alertable)
-{
- int res;
-
- if (alertable) {
- BreakCoopAlertableWaitUD ud;
-
- *alertable = FALSE;
- ud.cond = cond;
- ud.mutex = mutex;
- mono_thread_info_install_interrupt (break_coop_alertable_wait, &ud, alertable);
- if (*alertable)
- return 0;
- }
- res = mono_coop_cond_timedwait (cond, mutex, timeout_ms);
- if (alertable) {
- mono_thread_info_uninstall_interrupt (alertable);
- if (*alertable)
- return 0;
- }
- return res;
-}
-
static gboolean
add_thread_to_finalize (MonoInternalThread *thread, MonoError *error)
{
req = g_new0 (DomainFinalizationReq, 1);
req->domain = domain;
-
-#ifdef TARGET_WIN32
- req->done_event = CreateEvent (NULL, TRUE, FALSE, NULL);
- if (req->done_event == NULL) {
- g_free (req);
- return FALSE;
- }
-#else
- mono_coop_cond_init (&req->cond);
- mono_coop_mutex_init (&req->mutex);
-#endif
+ mono_coop_sem_init (&req->done, 0);
if (domain == mono_get_root_domain ())
finalizing_root_domain = TRUE;
if (timeout == -1)
timeout = INFINITE;
-#if TARGET_WIN32
- while (TRUE) {
- guint32 res = guarded_wait (req->done_event, timeout, TRUE);
- /* printf ("WAIT RES: %d.\n", res); */
-
- if (res == WAIT_IO_COMPLETION) {
- if ((thread->state & (ThreadState_StopRequested | ThreadState_SuspendRequested)) != 0)
- return FALSE;
- } else if (res == WAIT_TIMEOUT) {
- /* We leak the handle here */
- return FALSE;
- } else {
+ for (;;) {
+ res = mono_coop_sem_timedwait (&req->done, timeout, MONO_SEM_FLAGS_ALERTABLE);
+ if (res == MONO_SEM_TIMEDWAIT_RET_SUCCESS) {
break;
- }
- }
-
- CloseHandle (req->done_event);
-#else
- mono_coop_mutex_lock (&req->mutex);
- while (!req->done) {
- gboolean alerted;
- int res = coop_cond_timedwait_alertable (&req->cond, &req->mutex, timeout, &alerted);
- if (alerted) {
- if ((thread->state & (ThreadState_StopRequested | ThreadState_SuspendRequested)) != 0) {
- mono_coop_mutex_unlock (&req->mutex);
+ } else if (res == MONO_SEM_TIMEDWAIT_RET_ALERTED) {
+ if ((thread->state & (ThreadState_StopRequested | ThreadState_SuspendRequested)) != 0)
return FALSE;
- }
- } else if (res == -1) {
- /* We leak the cond/mutex here */
- mono_coop_mutex_unlock (&req->mutex);
+ } else if (res == MONO_SEM_TIMEDWAIT_RET_TIMEDOUT) {
return FALSE;
} else {
- break;
+ g_error ("%s: unknown result %d", __func__, res);
}
}
- mono_coop_mutex_unlock (&req->mutex);
/* When we reach here, the other thread has already exited the critical section, so this is safe to free */
- mono_coop_cond_destroy (&req->cond);
- mono_coop_mutex_destroy (&req->mutex);
+ mono_coop_sem_destroy (&req->done);
g_free (req);
-#endif
if (domain == mono_get_root_domain ()) {
mono_threadpool_ms_cleanup ();
reference_queue_clear_for_domain (domain);
/* printf ("DONE.\n"); */
-#if TARGET_WIN32
- SetEvent (req->done_event);
-
- /* The event is closed in mono_domain_finalize if we get here */
- g_free (req);
-#else
- mono_coop_mutex_lock (&req->mutex);
- req->done = TRUE;
- mono_coop_cond_signal (&req->cond);
- mono_coop_mutex_unlock (&req->mutex);
-#endif
+ mono_coop_sem_post (&req->done);
}
static guint32