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; }
static void thread_own_mutex (MonoInternalThread *internal, gpointer handle, MonoW32Handle *handle_data) { /* if we are not on the current thread, there is a * race condition when allocating internal->owned_mutexes */ g_assert (mono_thread_internal_is_current (internal)); if (!internal->owned_mutexes) internal->owned_mutexes = g_ptr_array_new (); g_ptr_array_add (internal->owned_mutexes, mono_w32handle_duplicate (handle_data)); }
static void thread_disown_mutex (MonoInternalThread *internal, gpointer handle) { gboolean removed; g_assert (mono_thread_internal_is_current (internal)); g_assert (internal->owned_mutexes); removed = g_ptr_array_remove (internal->owned_mutexes, handle); g_assert (removed); mono_w32handle_unref (handle); }