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; }
gpointer ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoStringHandle name, MonoBoolean *created, MonoError *error) { gpointer mutex; *created = TRUE; /* Need to blow away any old errors here, because code tests * for ERROR_ALREADY_EXISTS on success (!) to see if a mutex * was freshly created */ mono_w32error_set_last (ERROR_SUCCESS); if (MONO_HANDLE_IS_NULL (name)) { mutex = mutex_create (owned); } else { gchar *utf8_name = mono_string_handle_to_utf8 (name, error); return_val_if_nok (error, NULL); mutex = namedmutex_create (owned, utf8_name); if (mono_w32error_get_last () == ERROR_ALREADY_EXISTS) *created = FALSE; g_free (utf8_name); } return mutex; }
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; }
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; }
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; }
gpointer ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoString *name, MonoBoolean *created) { gpointer mutex; *created = TRUE; /* Need to blow away any old errors here, because code tests * for ERROR_ALREADY_EXISTS on success (!) to see if a mutex * was freshly created */ mono_w32error_set_last (ERROR_SUCCESS); if (!name) { mutex = mutex_create (owned); } else { mutex = namedmutex_create (owned, mono_string_chars (name)); if (mono_w32error_get_last () == ERROR_ALREADY_EXISTS) *created = FALSE; } return mutex; }
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; }
void mono_w32socket_set_last_error (gint32 error) { mono_w32error_set_last (error); }
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; }