Esempio n. 1
0
/*
 * 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)
{
	BreakCoopAlertableWaitUD *ud;
	int res;

	if (alertable) {
		ud = g_new0 (BreakCoopAlertableWaitUD, 1);
		ud->cond = cond;
		ud->mutex = mutex;

		mono_thread_info_install_interrupt (break_coop_alertable_wait, ud, alertable);
		if (*alertable) {
			g_free (ud);
			return 0;
		}
	}
	res = mono_coop_cond_timedwait (cond, mutex, timeout_ms);
	if (alertable) {
		mono_thread_info_uninstall_interrupt (alertable);
		if (*alertable)
			return 0;
		else {
			/* the interrupt token has not been taken by another
			 * thread, so it's our responsability to free it up. */
			g_free (ud);
		}
	}
	return res;
}
Esempio n. 2
0
static inline guint32
sleep_interruptable (guint32 ms, gboolean *alerted)
{
	guint32 start, now, end;

	g_assert (INFINITE == G_MAXUINT32);

	g_assert (alerted);
	*alerted = FALSE;

	start = mono_msec_ticks ();

	if (start < G_MAXUINT32 - ms) {
		end = start + ms;
	} else {
		/* start + ms would overflow guint32 */
		end = G_MAXUINT32;
	}

	mono_lazy_initialize (&sleep_init, sleep_initialize);

	mono_coop_mutex_lock (&sleep_mutex);

	for (now = mono_msec_ticks (); ms == INFINITE || now - start < ms; now = mono_msec_ticks ()) {
		mono_thread_info_install_interrupt (sleep_interrupt, NULL, alerted);
		if (*alerted) {
			mono_coop_mutex_unlock (&sleep_mutex);
			return WAIT_IO_COMPLETION;
		}

		if (ms < INFINITE)
			mono_coop_cond_timedwait (&sleep_cond, &sleep_mutex, end - now);
		else
			mono_coop_cond_wait (&sleep_cond, &sleep_mutex);

		mono_thread_info_uninstall_interrupt (alerted);
		if (*alerted) {
			mono_coop_mutex_unlock (&sleep_mutex);
			return WAIT_IO_COMPLETION;
		}
	}

	mono_coop_mutex_unlock (&sleep_mutex);

	return 0;
}
Esempio n. 3
0
static inline guint32
sleep_interruptable (guint32 ms, gboolean *alerted)
{
	gint64 now, end;

	g_assert (INFINITE == G_MAXUINT32);

	g_assert (alerted);
	*alerted = FALSE;

	if (ms != INFINITE)
		end = mono_100ns_ticks () + (ms * 1000 * 10);

	mono_lazy_initialize (&sleep_init, sleep_initialize);

	mono_coop_mutex_lock (&sleep_mutex);

	for (;;) {
		if (ms != INFINITE) {
			now = mono_100ns_ticks ();
			if (now > end)
				break;
		}

		mono_thread_info_install_interrupt (sleep_interrupt, NULL, alerted);
		if (*alerted) {
			mono_coop_mutex_unlock (&sleep_mutex);
			return WAIT_IO_COMPLETION;
		}

		if (ms != INFINITE)
			mono_coop_cond_timedwait (&sleep_cond, &sleep_mutex, (end - now) / 10 / 1000);
		else
			mono_coop_cond_wait (&sleep_cond, &sleep_mutex);

		mono_thread_info_uninstall_interrupt (alerted);
		if (*alerted) {
			mono_coop_mutex_unlock (&sleep_mutex);
			return WAIT_IO_COMPLETION;
		}
	}

	mono_coop_mutex_unlock (&sleep_mutex);

	return 0;
}