예제 #1
0
void
mono_os_event_destroy (MonoOSEvent *event)
{
	g_assert (mono_lazy_is_initialized (&status));

	g_assert (event);

	if (event->conds->len > 0)
		g_error ("%s: cannot destroy osevent, there are still %d threads waiting on it", __func__, event->conds->len);

	g_ptr_array_free (event->conds, TRUE);
}
예제 #2
0
void
mono_os_event_reset (MonoOSEvent *event)
{
	g_assert (mono_lazy_is_initialized (&status));

	g_assert (event);

	mono_os_mutex_lock (&signal_mutex);

	event->signalled = FALSE;

	mono_os_mutex_unlock (&signal_mutex);
}
예제 #3
0
void
mono_os_event_set (MonoOSEvent *event)
{
	gsize i;

	g_assert (mono_lazy_is_initialized (&status));

	g_assert (event);

	mono_os_mutex_lock (&signal_mutex);

	event->signalled = TRUE;

	for (i = 0; i < event->conds->len; ++i)
		mono_os_cond_signal ((mono_cond_t*) event->conds->pdata [i]);

	mono_os_mutex_unlock (&signal_mutex);
}
예제 #4
0
void
mono_threadpool_ms_io_remove_domain_jobs (MonoDomain *domain)
{
	ThreadPoolIOUpdate *update;

	if (!mono_lazy_is_initialized (&io_status))
		return;

	mono_mutex_lock (&threadpool_io->updates_lock);

	update = update_get_new ();
	update->type = UPDATE_REMOVE_DOMAIN;
	update->data.remove_domain.domain = domain;
	mono_memory_barrier (); /* Ensure this is safely published before we wake up the selector */

	selector_thread_wakeup ();

	mono_cond_wait (&threadpool_io->updates_cond, &threadpool_io->updates_lock);

	mono_mutex_unlock (&threadpool_io->updates_lock);
}
예제 #5
0
void
mono_threadpool_ms_io_remove_socket (int fd)
{
	ThreadPoolIOUpdate *update;

	if (!mono_lazy_is_initialized (&io_status))
		return;

	mono_mutex_lock (&threadpool_io->updates_lock);

	update = update_get_new ();
	update->type = UPDATE_REMOVE_SOCKET;
	update->data.add.fd = fd;
	mono_memory_barrier (); /* Ensure this is safely published before we wake up the selector */

	selector_thread_wakeup ();

	mono_cond_wait (&threadpool_io->updates_cond, &threadpool_io->updates_lock);

	mono_mutex_unlock (&threadpool_io->updates_lock);
}
예제 #6
0
MonoOSEventWaitRet
mono_os_event_wait_multiple (MonoOSEvent **events, gsize nevents, gboolean waitall, guint32 timeout, gboolean alertable)
{
	MonoOSEventWaitRet ret;
	mono_cond_t signal_cond;
	OSEventWaitData *data;
	gboolean alerted;
	gint64 start;
	gint i;

	g_assert (mono_lazy_is_initialized (&status));

	g_assert (events);
	g_assert (nevents > 0);
	g_assert (nevents <= MONO_OS_EVENT_WAIT_MAXIMUM_OBJECTS);

	for (i = 0; i < nevents; ++i)
		g_assert (events [i]);

	if (alertable) {
		data = g_new0 (OSEventWaitData, 1);
		data->ref = 2;
		mono_os_event_init (&data->event, FALSE);

		alerted = FALSE;
		mono_thread_info_install_interrupt (signal_and_unref, data, &alerted);
		if (alerted) {
			mono_os_event_destroy (&data->event);
			g_free (data);
			return MONO_OS_EVENT_WAIT_RET_ALERTED;
		}
	}

	if (timeout != MONO_INFINITE_WAIT)
		start = mono_msec_ticks ();

	mono_os_cond_init (&signal_cond);

	mono_os_mutex_lock (&signal_mutex);

	for (i = 0; i < nevents; ++i)
		g_ptr_array_add (events [i]->conds, &signal_cond);

	if (alertable)
		g_ptr_array_add (data->event.conds, &signal_cond);

	for (;;) {
		gint count, lowest;
		gboolean signalled;

		count = 0;
		lowest = -1;

		for (i = 0; i < nevents; ++i) {
			if (mono_os_event_is_signalled (events [i])) {
				count += 1;
				if (lowest == -1)
					lowest = i;
			}
		}

		if (alertable && mono_os_event_is_signalled (&data->event))
			signalled = TRUE;
		else if (waitall)
			signalled = (count == nevents);
		else /* waitany */
			signalled = (count > 0);

		if (signalled) {
			ret = MONO_OS_EVENT_WAIT_RET_SUCCESS_0 + lowest;
			goto done;
		}

		if (timeout == MONO_INFINITE_WAIT) {
			mono_os_cond_wait (&signal_cond, &signal_mutex);
		} else {
			gint64 elapsed;
			gint res;

			elapsed = mono_msec_ticks () - start;
			if (elapsed >= timeout) {
				ret = MONO_OS_EVENT_WAIT_RET_TIMEOUT;
				goto done;
			}

			res = mono_os_cond_timedwait (&signal_cond, &signal_mutex, timeout - elapsed);
			if (res != 0) {
				ret = MONO_OS_EVENT_WAIT_RET_TIMEOUT;
				goto done;
			}
		}
	}

done:
	for (i = 0; i < nevents; ++i)
		g_ptr_array_remove (events [i]->conds, &signal_cond);

	if (alertable)
		g_ptr_array_remove (data->event.conds, &signal_cond);

	mono_os_mutex_unlock (&signal_mutex);

	mono_os_cond_destroy (&signal_cond);

	if (alertable) {
		mono_thread_info_uninstall_interrupt (&alerted);
		if (alerted) {
			if (InterlockedDecrement ((gint32*) &data->ref) == 0) {
				mono_os_event_destroy (&data->event);
				g_free (data);
			}
			return MONO_OS_EVENT_WAIT_RET_ALERTED;
		}

		mono_os_event_destroy (&data->event);
		g_free (data);
	}

	return ret;
}