Ejemplo n.º 1
0
void
mono_w32mutex_abandon (MonoInternalThread *internal_raw)
{
	HANDLE_FUNCTION_ENTER ()

	MONO_HANDLE_DCL (MonoInternalThread, internal);

	g_assert (mono_thread_internal_is_current_handle (internal));

	if (!MONO_HANDLE_GETVAL (internal, owned_mutexes))
		goto exit;

	while (MONO_HANDLE_GETVAL (internal, owned_mutexes)->len) {
		MonoW32Handle *handle_data;
		MonoW32HandleMutex *mutex_handle;
		MonoNativeThreadId tid;
		gpointer handle;

		handle = g_ptr_array_index (MONO_HANDLE_GETVAL (internal, owned_mutexes), 0);

		if (!mono_w32handle_lookup_and_ref (handle, &handle_data))
			g_error ("%s: unkown handle %p", __func__, handle);

		if (handle_data->type != MONO_W32TYPE_MUTEX && handle_data->type != MONO_W32TYPE_NAMEDMUTEX)
			g_error ("%s: unkown mutex handle %p", __func__, handle);

		mutex_handle = (MonoW32HandleMutex*) handle_data->specific;

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: abandoning %s handle %p",
			__func__, mono_w32handle_get_typename (handle_data->type), handle);

		tid = MONO_UINT_TO_NATIVE_THREAD_ID (MONO_HANDLE_GETVAL (internal, tid));

		if (!pthread_equal (mutex_handle->tid, tid))
			g_error ("%s: trying to release mutex %p acquired by thread %p from thread %p",
				__func__, handle, (gpointer) mutex_handle->tid, (gpointer) tid);

		mono_w32handle_lock (handle_data);

		mutex_handle->recursion = 0;
		mutex_handle->tid = 0;
		mutex_handle->abandoned = TRUE;

		mono_w32handle_set_signal_state (handle_data, TRUE, FALSE);

		thread_disown_mutex (internal, handle);

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: abandoned %s handle %p",
			__func__, mono_w32handle_get_typename (handle_data->type), handle);

		mono_w32handle_unlock (handle_data);
		mono_w32handle_unref (handle_data);
	}

	g_ptr_array_free (MONO_HANDLE_GETVAL (internal, owned_mutexes), TRUE);
	MONO_HANDLE_SETVAL(internal, owned_mutexes, GPtrArray*, NULL);

exit:
	HANDLE_FUNCTION_RETURN ();
}
Ejemplo n.º 2
0
static gpointer
sem_handle_create (MonoW32HandleSemaphore *sem_handle, MonoW32HandleType type, gint32 initial, gint32 max)
{
	gpointer handle;

	sem_handle->val = initial;
	sem_handle->max = max;

	handle = mono_w32handle_new (type, sem_handle);
	if (handle == INVALID_HANDLE_VALUE) {
		g_warning ("%s: error creating %s handle",
			__func__, mono_w32handle_get_typename (type));
		SetLastError (ERROR_GEN_FAILURE);
		return NULL;
	}

	mono_w32handle_lock_handle (handle);

	if (initial != 0)
		mono_w32handle_set_signal_state (handle, TRUE, FALSE);

	mono_w32handle_unlock_handle (handle);

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created %s handle %p",
		__func__, mono_w32handle_get_typename (type), handle);

	return handle;
}
Ejemplo n.º 3
0
static gboolean
mutex_handle_own (gpointer handle, MonoW32HandleType type, gboolean *abandoned)
{
	MonoW32HandleMutex *mutex_handle;

	*abandoned = FALSE;

	if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
		g_warning ("%s: error looking up %s handle %p", __func__, mono_w32handle_get_typename (type), handle);
		return FALSE;
	}

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning %s handle %p, before: [tid: %p, recursion: %d], after: [tid: %p, recursion: %d], abandoned: %s",
		__func__, mono_w32handle_get_typename (type), handle, (gpointer) mutex_handle->tid, mutex_handle->recursion, (gpointer) pthread_self (), mutex_handle->recursion + 1, mutex_handle->abandoned ? "true" : "false");

	if (mutex_handle->recursion != 0) {
		g_assert (pthread_equal (pthread_self (), mutex_handle->tid));
		mutex_handle->recursion++;
	} else {
		mutex_handle->tid = pthread_self ();
		mutex_handle->recursion = 1;

		thread_own_mutex (mono_thread_internal_current (), handle);
	}

	if (mutex_handle->abandoned) {
		mutex_handle->abandoned = FALSE;
		*abandoned = TRUE;
	}

	mono_w32handle_set_signal_state (handle, FALSE, FALSE);

	return TRUE;
}
Ejemplo n.º 4
0
static void
mutex_handle_signal (MonoW32Handle *handle_data)
{
	MonoW32HandleMutex *mutex_handle;
	pthread_t tid;

	mutex_handle = (MonoW32HandleMutex*) handle_data->specific;

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: signalling %s handle %p, tid: %p recursion: %d",
		__func__, mono_w32handle_get_typename (handle_data->type), handle_data, (gpointer) mutex_handle->tid, mutex_handle->recursion);

	tid = pthread_self ();

	if (mutex_handle->abandoned) {
		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: %s handle %p is abandoned",
			__func__, mono_w32handle_get_typename (handle_data->type), handle_data);
	} else if (!pthread_equal (mutex_handle->tid, tid)) {
		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: we don't own %s handle %p (owned by %ld, me %ld)",
			__func__, mono_w32handle_get_typename (handle_data->type), handle_data, (long)mutex_handle->tid, (long)tid);
	} else {
		/* OK, we own this mutex */
		mutex_handle->recursion--;

		if (mutex_handle->recursion == 0) {
			thread_disown_mutex (mono_thread_internal_current (), handle_data);

			mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: unlocking %s handle %p, tid: %p recusion : %d",
				__func__, mono_w32handle_get_typename (handle_data->type), handle_data, (gpointer) mutex_handle->tid, mutex_handle->recursion);

			mutex_handle->tid = 0;
			mono_w32handle_set_signal_state (handle_data, TRUE, FALSE);
		}
	}
}
Ejemplo n.º 5
0
MonoBoolean
ves_icall_System_Threading_Mutex_ReleaseMutex_internal (gpointer handle)
{
	MonoW32Handle *handle_data;
	MonoW32HandleMutex *mutex_handle;
	pthread_t tid;
	gboolean ret;

	if (!mono_w32handle_lookup_and_ref (handle, &handle_data)) {
		g_warning ("%s: unkown handle %p", __func__, handle);
		mono_w32error_set_last (ERROR_INVALID_HANDLE);
		return FALSE;
	}

	if (handle_data->type != MONO_W32TYPE_MUTEX && handle_data->type != MONO_W32TYPE_NAMEDMUTEX) {
		g_warning ("%s: unknown mutex handle %p", __func__, handle);
		mono_w32error_set_last (ERROR_INVALID_HANDLE);
		mono_w32handle_unref (handle_data);
		return FALSE;
	}

	mutex_handle = (MonoW32HandleMutex*) handle_data->specific;

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: releasing %s handle %p, tid: %p recursion: %d",
		__func__, mono_w32handle_get_typename (handle_data->type), handle, (gpointer) mutex_handle->tid, mutex_handle->recursion);

	mono_w32handle_lock (handle_data);

	tid = pthread_self ();

	if (mutex_handle->abandoned) {
		// The Win32 ReleaseMutex() function returns TRUE for abandoned mutexes
		ret = TRUE;
	} else if (!pthread_equal (mutex_handle->tid, tid)) {
		ret = FALSE;

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: we don't own %s handle %p (owned by %ld, me %ld)",
			    __func__, mono_w32handle_get_typename (handle_data->type), handle, (long)mutex_handle->tid, (long)tid);
	} else {
		ret = TRUE;

		/* OK, we own this mutex */
		mutex_handle->recursion--;

		if (mutex_handle->recursion == 0) {
			thread_disown_mutex (mono_thread_internal_current_handle (), handle);

			mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: unlocking %s handle %p, tid: %p recusion : %d",
				__func__, mono_w32handle_get_typename (handle_data->type), handle, (gpointer) mutex_handle->tid, mutex_handle->recursion);

			mutex_handle->tid = 0;
			mono_w32handle_set_signal_state (handle_data, TRUE, FALSE);
		}
	}

	mono_w32handle_unlock (handle_data);
	mono_w32handle_unref (handle_data);

	return ret;
}
Ejemplo n.º 6
0
static gpointer mutex_handle_create (MonoW32HandleMutex *mutex_handle, MonoW32HandleType type, gboolean owned)
{
	gpointer handle;
	gboolean abandoned;

	mutex_handle->tid = 0;
	mutex_handle->recursion = 0;
	mutex_handle->abandoned = FALSE;

	handle = mono_w32handle_new (type, mutex_handle);
	if (handle == INVALID_HANDLE_VALUE) {
		g_warning ("%s: error creating %s handle",
			__func__, mono_w32handle_get_typename (type));
		mono_w32error_set_last (ERROR_GEN_FAILURE);
		return NULL;
	}

	mono_w32handle_lock_handle (handle);

	if (owned)
		mutex_handle_own (handle, type, &abandoned);
	else
		mono_w32handle_set_signal_state (handle, TRUE, FALSE);

	mono_w32handle_unlock_handle (handle);

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created %s handle %p",
		__func__, mono_w32handle_get_typename (type), handle);

	return handle;
}
Ejemplo n.º 7
0
MonoBoolean
ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (gpointer handle, gint32 releaseCount, gint32 *prevcount)
{
	MonoW32HandleType type;
	MonoW32HandleSemaphore *sem_handle;
	MonoBoolean ret;

	if (!handle) {
		SetLastError (ERROR_INVALID_HANDLE);
		return FALSE;
	}

	switch (type = mono_w32handle_get_type (handle)) {
	case MONO_W32HANDLE_SEM:
	case MONO_W32HANDLE_NAMEDSEM:
		break;
	default:
		SetLastError (ERROR_INVALID_HANDLE);
		return FALSE;
	}

	if (!mono_w32handle_lookup (handle, type, (gpointer *)&sem_handle)) {
		g_warning ("%s: error looking up sem handle %p", __func__, handle);
		return FALSE;
	}

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: releasing %s handle %p",
		__func__, mono_w32handle_get_typename (type), handle);

	mono_w32handle_lock_handle (handle);

	/* Do this before checking for count overflow, because overflowing
	 * max is a listed technique for finding the current value */
	if (prevcount)
		*prevcount = sem_handle->val;

	/* No idea why max is signed, but thats the spec :-( */
	if (sem_handle->val + releaseCount > (guint32)sem_handle->max) {
		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s handle %p val %d count %d max %d, max value would be exceeded",
			__func__, mono_w32handle_get_typename (type), handle, sem_handle->val, releaseCount, sem_handle->max);

		ret = FALSE;
	} else {
		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s handle %p val %d count %d max %d",
			__func__, mono_w32handle_get_typename (type), handle, sem_handle->val, releaseCount, sem_handle->max);

		sem_handle->val += releaseCount;
		mono_w32handle_set_signal_state (handle, TRUE, TRUE);

		ret = TRUE;
	}

	mono_w32handle_unlock_handle (handle);

	return ret;
}
Ejemplo n.º 8
0
void
mono_w32mutex_abandon (MonoInternalThread *internal)
{
	g_assert (mono_thread_internal_is_current (internal));

	if (!internal->owned_mutexes)
		return;

	while (internal->owned_mutexes->len) {
		MonoW32Handle *handle_data;
		MonoW32HandleMutex *mutex_handle;
		MonoNativeThreadId tid;
		gpointer handle;

		handle = g_ptr_array_index (internal->owned_mutexes, 0);

		if (!mono_w32handle_lookup_and_ref (handle, &handle_data))
			g_error ("%s: unkown handle %p", __func__, handle);

		if (handle_data->type != MONO_W32TYPE_MUTEX && handle_data->type != MONO_W32TYPE_NAMEDMUTEX)
			g_error ("%s: unkown mutex handle %p", __func__, handle);

		mutex_handle = (MonoW32HandleMutex*) handle_data->specific;

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: abandoning %s handle %p",
			__func__, mono_w32handle_get_typename (handle_data->type), handle);

		tid = MONO_UINT_TO_NATIVE_THREAD_ID (internal->tid);

		if (!pthread_equal (mutex_handle->tid, tid))
			g_error ("%s: trying to release mutex %p acquired by thread %p from thread %p",
				__func__, handle, (gpointer) mutex_handle->tid, (gpointer) tid);

		mono_w32handle_lock (handle_data);

		mutex_handle->recursion = 0;
		mutex_handle->tid = 0;
		mutex_handle->abandoned = TRUE;

		mono_w32handle_set_signal_state (handle_data, TRUE, FALSE);

		thread_disown_mutex (internal, handle);

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: abandoned %s handle %p",
			__func__, mono_w32handle_get_typename (handle_data->type), handle);

		mono_w32handle_unlock (handle_data);
		mono_w32handle_unref (handle_data);
	}

	g_ptr_array_free (internal->owned_mutexes, TRUE);
	internal->owned_mutexes = NULL;
}
Ejemplo n.º 9
0
static gpointer event_create (gboolean manual, gboolean initial)
{
	MonoW32HandleEvent event_handle;
	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_EVENT, "%s: creating %s handle",
		__func__, mono_w32handle_get_typename (MONO_W32TYPE_EVENT));
	return event_handle_create (&event_handle, MONO_W32TYPE_EVENT, manual, initial);
}
Ejemplo n.º 10
0
static gboolean
mutex_handle_own (MonoW32Handle *handle_data, gboolean *abandoned)
{
	HANDLE_FUNCTION_ENTER ();

	MonoW32HandleMutex *mutex_handle;

	*abandoned = FALSE;

	mutex_handle = (MonoW32HandleMutex*) handle_data->specific;

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: owning %s handle %p, before: [tid: %p, recursion: %d], after: [tid: %p, recursion: %d], abandoned: %s",
		__func__, mono_w32handle_get_typename (handle_data->type), handle_data, (gpointer) mutex_handle->tid, mutex_handle->recursion, (gpointer) pthread_self (), mutex_handle->recursion + 1, mutex_handle->abandoned ? "true" : "false");

	if (mutex_handle->recursion != 0) {
		g_assert (pthread_equal (pthread_self (), mutex_handle->tid));
		mutex_handle->recursion++;
	} else {
		mutex_handle->tid = pthread_self ();
		mutex_handle->recursion = 1;

		thread_own_mutex (mono_thread_internal_current_handle (), handle_data, handle_data);
	}

	if (mutex_handle->abandoned) {
		mutex_handle->abandoned = FALSE;
		*abandoned = TRUE;
	}

	mono_w32handle_set_signal_state (handle_data, FALSE, FALSE);

	HANDLE_FUNCTION_RETURN_VAL (TRUE);
}
Ejemplo n.º 11
0
static gpointer mutex_create (gboolean owned)
{
	MonoW32HandleMutex mutex_handle;
	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: creating %s handle",
		__func__, mono_w32handle_get_typename (MONO_W32TYPE_MUTEX));
	return mutex_handle_create (&mutex_handle, MONO_W32TYPE_MUTEX, owned);
}
Ejemplo n.º 12
0
static gpointer
sem_create (gint32 initial, gint32 max)
{
	MonoW32HandleSemaphore sem_handle;
	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle, initial %d max %d",
		__func__, mono_w32handle_get_typename (MONO_W32HANDLE_SEM), initial, max);
	return sem_handle_create (&sem_handle, MONO_W32HANDLE_SEM, initial, max);
}
Ejemplo n.º 13
0
static void mutex_handle_prewait (gpointer handle, MonoW32HandleType type)
{
	/* If the mutex is not currently owned, do nothing and let the
	 * usual wait carry on.  If it is owned, check that the owner
	 * is still alive; if it isn't we override the previous owner
	 * and assume that process exited abnormally and failed to
	 * clean up.
	 */
	MonoW32HandleMutex *mutex_handle;

	if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
		g_warning ("%s: error looking up %s handle %p",
			__func__, mono_w32handle_get_typename (type), handle);
		return;
	}

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: pre-waiting %s handle %p, owned? %s",
		__func__, mono_w32handle_get_typename (type), handle, mutex_handle->recursion != 0 ? "true" : "false");
}
Ejemplo n.º 14
0
static gboolean
mutex_handle_is_owned (MonoW32Handle *handle_data)
{
	MonoW32HandleMutex *mutex_handle;

	mutex_handle = (MonoW32HandleMutex*) handle_data->specific;

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: testing ownership %s handle %p",
		__func__, mono_w32handle_get_typename (handle_data->type), handle_data);

	if (mutex_handle->recursion > 0 && pthread_equal (mutex_handle->tid, pthread_self ())) {
		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: %s handle %p owned by %p",
			__func__, mono_w32handle_get_typename (handle_data->type), handle_data, (gpointer) pthread_self ());
		return TRUE;
	} else {
		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: %s handle %p not owned by %p, tid: %p recursion: %d",
			__func__, mono_w32handle_get_typename (handle_data->type), handle_data, (gpointer) pthread_self (), (gpointer) mutex_handle->tid, mutex_handle->recursion);
		return FALSE;
	}
}
Ejemplo n.º 15
0
static gpointer mutex_handle_create (MonoW32HandleMutex *mutex_handle, MonoW32Type type, gboolean owned)
{
	MonoW32Handle *handle_data;
	gpointer handle;
	gboolean abandoned;

	mutex_handle->tid = 0;
	mutex_handle->recursion = 0;
	mutex_handle->abandoned = FALSE;

	handle = mono_w32handle_new (type, mutex_handle);
	if (handle == INVALID_HANDLE_VALUE) {
		g_warning ("%s: error creating %s handle",
			__func__, mono_w32handle_get_typename (type));
		mono_w32error_set_last (ERROR_GEN_FAILURE);
		return NULL;
	}

	if (!mono_w32handle_lookup_and_ref (handle, &handle_data))
		g_error ("%s: unkown handle %p", __func__, handle);

	if (handle_data->type != type)
		g_error ("%s: unknown mutex handle %p", __func__, handle);

	mono_w32handle_lock (handle_data);

	if (owned)
		mutex_handle_own (handle_data, &abandoned);
	else
		mono_w32handle_set_signal_state (handle_data, TRUE, FALSE);

	mono_w32handle_unlock (handle_data);

	/* Balance mono_w32handle_lookup_and_ref */
	mono_w32handle_unref (handle_data);

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: created %s handle %p",
		__func__, mono_w32handle_get_typename (type), handle);

	return handle;
}
Ejemplo n.º 16
0
static gboolean sem_handle_own (gpointer handle, MonoW32HandleType type, guint32 *statuscode)
{
	MonoW32HandleSemaphore *sem_handle;

	*statuscode = WAIT_OBJECT_0;

	if (!mono_w32handle_lookup (handle, type, (gpointer *)&sem_handle)) {
		g_warning ("%s: error looking up %s handle %p",
			__func__, mono_w32handle_get_typename (type), handle);
		return FALSE;
	}

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning %s handle %p",
		__func__, mono_w32handle_get_typename (type), handle);

	sem_handle->val--;

	if (sem_handle->val == 0)
		mono_w32handle_set_signal_state (handle, FALSE, FALSE);

	return TRUE;
}
Ejemplo n.º 17
0
static gboolean
mutex_handle_is_owned (gpointer handle, MonoW32HandleType type)
{
	MonoW32HandleMutex *mutex_handle;

	if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
		g_warning ("%s: error looking up %s handle %p", __func__, mono_w32handle_get_typename (type), handle);
		return FALSE;
	}

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: testing ownership %s handle %p",
		__func__, mono_w32handle_get_typename (type), handle);

	if (mutex_handle->recursion > 0 && pthread_equal (mutex_handle->tid, pthread_self ())) {
		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s handle %p owned by %p",
			__func__, mono_w32handle_get_typename (type), handle, (gpointer) pthread_self ());
		return TRUE;
	} else {
		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s handle %p not owned by %p, tid: %p recursion: %d",
			__func__, mono_w32handle_get_typename (type), handle, (gpointer) pthread_self (), (gpointer) mutex_handle->tid, mutex_handle->recursion);
		return FALSE;
	}
}
Ejemplo n.º 18
0
static void mutex_handle_prewait (MonoW32Handle *handle_data)
{
	/* If the mutex is not currently owned, do nothing and let the
	 * usual wait carry on.  If it is owned, check that the owner
	 * is still alive; if it isn't we override the previous owner
	 * and assume that process exited abnormally and failed to
	 * clean up.
	 */
	MonoW32HandleMutex *mutex_handle;

	mutex_handle = (MonoW32HandleMutex*) handle_data->specific;

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: pre-waiting %s handle %p, owned? %s",
		__func__, mono_w32handle_get_typename (handle_data->type), handle_data, mutex_handle->recursion != 0 ? "true" : "false");
}
Ejemplo n.º 19
0
static gpointer event_handle_create (MonoW32HandleEvent *event_handle, MonoW32Type type, gboolean manual, gboolean initial)
{
	MonoW32Handle *handle_data;
	gpointer handle;

	event_handle->manual = manual;
	event_handle->set_count = (initial && !manual) ? 1 : 0;

	handle = mono_w32handle_new (type, event_handle);
	if (handle == INVALID_HANDLE_VALUE) {
		g_warning ("%s: error creating %s handle",
			__func__, mono_w32handle_get_typename (type));
		mono_w32error_set_last (ERROR_GEN_FAILURE);
		return NULL;
	}

	if (!mono_w32handle_lookup_and_ref (handle, &handle_data))
		g_error ("%s: unkown handle %p", __func__, handle);

	if (handle_data->type != type)
		g_error ("%s: unknown event handle %p", __func__, handle);

	mono_w32handle_lock (handle_data);

	if (initial)
		mono_w32handle_set_signal_state (handle_data, TRUE, FALSE);

	mono_w32handle_unlock (handle_data);

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_EVENT, "%s: created %s handle %p",
		__func__, mono_w32handle_get_typename (type), handle);

	mono_w32handle_unref (handle_data);

	return handle;
}
Ejemplo n.º 20
0
static void event_handle_signal (MonoW32Handle *handle_data)
{
	MonoW32HandleEvent *event_handle;

	event_handle = (MonoW32HandleEvent*) handle_data->specific;

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_EVENT, "%s: signalling %s handle %p",
		__func__, mono_w32handle_get_typename (handle_data->type), handle_data);

	if (!event_handle->manual) {
		event_handle->set_count = 1;
		mono_w32handle_set_signal_state (handle_data, TRUE, FALSE);
	} else {
		mono_w32handle_set_signal_state (handle_data, TRUE, TRUE);
	}
}
Ejemplo n.º 21
0
gpointer
mono_w32handle_namespace_search_handle (MonoW32HandleType type, gchar *name)
{
	NamespaceSearchHandleData search_data;

	if (!has_namespace (type))
		g_error ("%s: type %s does not have a namespace", __func__, type);

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Lookup for handle named [%s] type %s",
		__func__, name, mono_w32handle_get_typename (type));

	search_data.ret = NULL;
	search_data.type = type;
	search_data.name = name;
	mono_w32handle_foreach (mono_w32handle_namespace_search_handle_callback, &search_data);
	return search_data.ret;
}
Ejemplo n.º 22
0
static gpointer
namedsem_create (gint32 initial, gint32 max, const gunichar2 *name)
{
	gpointer handle;
	gchar *utf8_name;

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle, initial %d max %d name \"%s\"",
		    __func__, mono_w32handle_get_typename (MONO_W32HANDLE_NAMEDSEM), initial, max, (const char*)name);

	/* w32 seems to guarantee that opening named objects can't race each other */
	mono_w32handle_namespace_lock ();

	utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating named sem name [%s] initial %d max %d", __func__, utf8_name, initial, max);

	handle = mono_w32handle_namespace_search_handle (MONO_W32HANDLE_NAMEDSEM, utf8_name);
	if (handle == INVALID_HANDLE_VALUE) {
		/* The name has already been used for a different object. */
		handle = NULL;
		SetLastError (ERROR_INVALID_HANDLE);
	} else if (handle) {
		/* Not an error, but this is how the caller is informed that the semaphore wasn't freshly created */
		SetLastError (ERROR_ALREADY_EXISTS);

		/* mono_w32handle_namespace_search_handle already adds a ref to the handle */
	} else {
		/* A new named semaphore */
		MonoW32HandleNamedSemaphore namedsem_handle;

		strncpy (&namedsem_handle.sharedns.name [0], utf8_name, MAX_PATH);
		namedsem_handle.sharedns.name [MAX_PATH] = '\0';

		handle = sem_handle_create ((MonoW32HandleSemaphore*) &namedsem_handle, MONO_W32HANDLE_NAMEDSEM, initial, max);
	}

	g_free (utf8_name);

	mono_w32handle_namespace_unlock ();

	return handle;
}
Ejemplo n.º 23
0
static gboolean
mono_w32handle_namespace_search_handle_callback (gpointer handle, gpointer data, gpointer user_data)
{
	NamespaceSearchHandleData *search_data;
	MonoW32HandleType type;
	MonoW32HandleNamespace *sharedns;

	type = mono_w32handle_get_type (handle);
	if (!has_namespace (type))
		return FALSE;

	search_data = (NamespaceSearchHandleData*) user_data;

	switch (type) {
	case MONO_W32HANDLE_NAMEDMUTEX: sharedns = mono_w32mutex_get_namespace ((MonoW32HandleNamedMutex*) data); break;
	case MONO_W32HANDLE_NAMEDSEM:   sharedns = mono_w32semaphore_get_namespace ((MonoW32HandleNamedSemaphore*) data); break;
	case MONO_W32HANDLE_NAMEDEVENT: sharedns = mono_w32event_get_namespace ((MonoW32HandleNamedEvent*) data); break;
	default:
		g_assert_not_reached ();
	}

	if (strcmp (sharedns->name, search_data->name) == 0) {
		if (type != search_data->type) {
			/* Its the wrong type, so fail now */
			mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p matches name but is wrong type: %s",
				__func__, handle, mono_w32handle_get_typename (type));
			search_data->ret = INVALID_HANDLE_VALUE;
		} else {
			mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p matches name and type",
				__func__, handle);

			/* we do not want the handle to be destroyed before we return it  */
			mono_w32handle_ref (handle);

			search_data->ret = handle;
		}

		return TRUE;
	}

	return FALSE;
}
Ejemplo n.º 24
0
static gpointer namedmutex_create (gboolean owned, const gunichar2 *name)
{
	gpointer handle;
	gchar *utf8_name;

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle",
		__func__, mono_w32handle_get_typename (MONO_W32HANDLE_NAMEDMUTEX));

	/* w32 seems to guarantee that opening named objects can't race each other */
	mono_w32handle_namespace_lock ();

	glong utf8_len = 0;
	utf8_name = g_utf16_to_utf8 (name, -1, NULL, &utf8_len, NULL);

	handle = mono_w32handle_namespace_search_handle (MONO_W32HANDLE_NAMEDMUTEX, utf8_name);
	if (handle == INVALID_HANDLE_VALUE) {
		/* The name has already been used for a different object. */
		handle = NULL;
		mono_w32error_set_last (ERROR_INVALID_HANDLE);
	} else if (handle) {
		/* Not an error, but this is how the caller is informed that the mutex wasn't freshly created */
		mono_w32error_set_last (ERROR_ALREADY_EXISTS);

		/* mono_w32handle_namespace_search_handle already adds a ref to the handle */
	} else {
		/* A new named mutex */
		MonoW32HandleNamedMutex namedmutex_handle;

		size_t len = utf8_len < MAX_PATH ? utf8_len : MAX_PATH;
		memcpy (&namedmutex_handle.sharedns.name [0], utf8_name, len);
		namedmutex_handle.sharedns.name [len] = '\0';

		handle = mutex_handle_create ((MonoW32HandleMutex*) &namedmutex_handle, MONO_W32HANDLE_NAMEDMUTEX, owned);
	}

	g_free (utf8_name);

	mono_w32handle_namespace_unlock ();

	return handle;
}
Ejemplo n.º 25
0
static gboolean event_handle_own (MonoW32Handle *handle_data, gboolean *abandoned)
{
	MonoW32HandleEvent *event_handle;

	*abandoned = FALSE;

	event_handle = (MonoW32HandleEvent*) handle_data->specific;

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_EVENT, "%s: owning %s handle %p",
		__func__, mono_w32handle_get_typename (handle_data->type), handle_data);

	if (!event_handle->manual) {
		g_assert (event_handle->set_count > 0);
		event_handle->set_count --;

		if (event_handle->set_count == 0)
			mono_w32handle_set_signal_state (handle_data, FALSE, FALSE);
	}

	return TRUE;
}
Ejemplo n.º 26
0
}

static gpointer event_create (gboolean manual, gboolean initial)
{
	MonoW32HandleEvent event_handle;
	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_EVENT, "%s: creating %s handle",
		__func__, mono_w32handle_get_typename (MONO_W32TYPE_EVENT));
	return event_handle_create (&event_handle, MONO_W32TYPE_EVENT, manual, initial);
}

static gpointer namedevent_create (gboolean manual, gboolean initial, const gchar *utf8_name G_GNUC_UNUSED)
{
	gpointer handle;

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_EVENT, "%s: creating %s handle",
		__func__, mono_w32handle_get_typename (MONO_W32TYPE_NAMEDEVENT));

	/* w32 seems to guarantee that opening named objects can't race each other */
	mono_w32handle_namespace_lock ();

	glong utf8_len = strlen (utf8_name);

	handle = mono_w32handle_namespace_search_handle (MONO_W32TYPE_NAMEDEVENT, utf8_name);
	if (handle == INVALID_HANDLE_VALUE) {
		/* The name has already been used for a different object. */
		handle = NULL;
		mono_w32error_set_last (ERROR_INVALID_HANDLE);
	} else if (handle) {
		/* Not an error, but this is how the caller is informed that the event wasn't freshly created */
		mono_w32error_set_last (ERROR_ALREADY_EXISTS);
Ejemplo n.º 27
0
void
mono_w32mutex_abandon (void)
{
	MonoInternalThread *internal;

	g_assert (mono_thread_internal_current_is_attached ());

	internal = mono_thread_internal_current ();
	g_assert (internal);

	if (!internal->owned_mutexes)
		return;

	while (internal->owned_mutexes->len) {
		MonoW32HandleType type;
		MonoW32HandleMutex *mutex_handle;
		MonoNativeThreadId tid;
		gpointer handle;

		handle = g_ptr_array_index (internal->owned_mutexes, 0);

		switch (type = mono_w32handle_get_type (handle)) {
		case MONO_W32HANDLE_MUTEX:
		case MONO_W32HANDLE_NAMEDMUTEX:
			break;
		default:
			g_assert_not_reached ();
		}

		if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
			g_error ("%s: error looking up %s handle %p",
				__func__, mono_w32handle_get_typename (type), handle);
		}

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: abandoning %s handle %p",
			__func__, mono_w32handle_get_typename (type), handle);

		tid = MONO_UINT_TO_NATIVE_THREAD_ID (internal->tid);

		if (!pthread_equal (mutex_handle->tid, tid))
			g_error ("%s: trying to release mutex %p acquired by thread %p from thread %p",
				__func__, handle, (gpointer) mutex_handle->tid, (gpointer) tid);

		mono_w32handle_lock_handle (handle);

		mutex_handle->recursion = 0;
		mutex_handle->tid = 0;
		mutex_handle->abandoned = TRUE;

		mono_w32handle_set_signal_state (handle, TRUE, FALSE);

		thread_disown_mutex (internal, handle);

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: abandoned %s handle %p",
			__func__, mono_w32handle_get_typename (type), handle);

		mono_w32handle_unlock_handle (handle);
	}

	g_ptr_array_free (internal->owned_mutexes, TRUE);
	internal->owned_mutexes = NULL;
}
Ejemplo n.º 28
0
MonoBoolean
ves_icall_System_Threading_Mutex_ReleaseMutex_internal (gpointer handle)
{
	MonoW32HandleType type;
	MonoW32HandleMutex *mutex_handle;
	pthread_t tid;
	gboolean ret;

	if (handle == NULL) {
		mono_w32error_set_last (ERROR_INVALID_HANDLE);
		return FALSE;
	}

	switch (type = mono_w32handle_get_type (handle)) {
	case MONO_W32HANDLE_MUTEX:
	case MONO_W32HANDLE_NAMEDMUTEX:
		break;
	default:
		mono_w32error_set_last (ERROR_INVALID_HANDLE);
		return FALSE;
	}

	if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
		g_warning ("%s: error looking up %s handle %p",
			__func__, mono_w32handle_get_typename (type), handle);
		return FALSE;
	}

	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: releasing %s handle %p, tid: %p recursion: %d",
		__func__, mono_w32handle_get_typename (type), handle, (gpointer) mutex_handle->tid, mutex_handle->recursion);

	mono_w32handle_lock_handle (handle);

	tid = pthread_self ();

	if (mutex_handle->abandoned) {
		// The Win32 ReleaseMutex() function returns TRUE for abandoned mutexes
		ret = TRUE;
	} else if (!pthread_equal (mutex_handle->tid, tid)) {
		ret = FALSE;

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: we don't own %s handle %p (owned by %ld, me %ld)",
			    __func__, mono_w32handle_get_typename (type), handle, (long)mutex_handle->tid, (long)tid);
	} else {
		ret = TRUE;

		/* OK, we own this mutex */
		mutex_handle->recursion--;

		if (mutex_handle->recursion == 0) {
			thread_disown_mutex (mono_thread_internal_current (), handle);

			mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking %s handle %p, tid: %p recusion : %d",
				__func__, mono_w32handle_get_typename (type), handle, (gpointer) mutex_handle->tid, mutex_handle->recursion);

			mutex_handle->tid = 0;
			mono_w32handle_set_signal_state (handle, TRUE, FALSE);
		}
	}

	mono_w32handle_unlock_handle (handle);

	return ret;
}