X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mono%2Fio-layer%2Fmutexes.c;h=dccbfb96f51e962c8b6414b8a72bc6a9e4060673;hb=931cbe5653f7a1402707efb4988d4658037ff61f;hp=e22c13e2dd14948d898619c61c3558ac41e59bf9;hpb=a3fde0a6b9dc924f8c75a18d28b920def41383f8;p=mono.git diff --git a/mono/io-layer/mutexes.c b/mono/io-layer/mutexes.c index e22c13e2dd1..dccbfb96f51 100644 --- a/mono/io-layer/mutexes.c +++ b/mono/io-layer/mutexes.c @@ -24,197 +24,145 @@ static void mutex_signal(gpointer handle); static gboolean mutex_own (gpointer handle); static gboolean mutex_is_owned (gpointer handle); +static void mutex_prewait (gpointer handle); +static void mutex_details (gpointer data); +static const gchar* mutex_typename (void); +static gsize mutex_typesize (void); static void namedmutex_signal (gpointer handle); static gboolean namedmutex_own (gpointer handle); static gboolean namedmutex_is_owned (gpointer handle); static void namedmutex_prewait (gpointer handle); +static void namedmutex_details (gpointer data); +static const gchar* namedmutex_typename (void); +static gsize namedmutex_typesize (void); -struct _WapiHandleOps _wapi_mutex_ops = { +static WapiHandleOps _wapi_mutex_ops = { NULL, /* close */ mutex_signal, /* signal */ mutex_own, /* own */ mutex_is_owned, /* is_owned */ NULL, /* special_wait */ - NULL /* prewait */ + mutex_prewait, /* prewait */ + mutex_details, /* details */ + mutex_typename, /* typename */ + mutex_typesize, /* typesize */ }; -void _wapi_mutex_details (gpointer handle_info) -{ - struct _WapiHandle_mutex *mut = (struct _WapiHandle_mutex *)handle_info; - -#ifdef PTHREAD_POINTER_ID - g_print ("own: %5p, count: %5u", mut->tid, mut->recursion); -#else - g_print ("own: %5ld, count: %5u", mut->tid, mut->recursion); -#endif -} - -struct _WapiHandleOps _wapi_namedmutex_ops = { +static WapiHandleOps _wapi_namedmutex_ops = { NULL, /* close */ namedmutex_signal, /* signal */ namedmutex_own, /* own */ namedmutex_is_owned, /* is_owned */ NULL, /* special_wait */ - namedmutex_prewait /* prewait */ + namedmutex_prewait, /* prewait */ + namedmutex_details, /* details */ + namedmutex_typename, /* typename */ + namedmutex_typesize, /* typesize */ }; -static gboolean mutex_release (gpointer handle); -static gboolean namedmutex_release (gpointer handle); - -static struct +void +_wapi_mutex_init (void) { - gboolean (*release)(gpointer handle); -} mutex_ops[WAPI_HANDLE_COUNT] = { - {NULL}, - {NULL}, - {NULL}, - {NULL}, - {NULL}, - {mutex_release}, - {NULL}, - {NULL}, - {NULL}, - {NULL}, - {NULL}, - {namedmutex_release}, -}; - -static mono_once_t mutex_ops_once=MONO_ONCE_INIT; + _wapi_handle_register_ops (WAPI_HANDLE_MUTEX, &_wapi_mutex_ops); + _wapi_handle_register_ops (WAPI_HANDLE_NAMEDMUTEX, &_wapi_namedmutex_ops); -static void mutex_ops_init (void) -{ _wapi_handle_register_capabilities (WAPI_HANDLE_MUTEX, (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SIGNAL | WAPI_HANDLE_CAP_OWN)); _wapi_handle_register_capabilities (WAPI_HANDLE_NAMEDMUTEX, (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SIGNAL | WAPI_HANDLE_CAP_OWN)); } -static void mutex_signal(gpointer handle) +static const char* mutex_handle_type_to_string (WapiHandleType type) { - ReleaseMutex(handle); + switch (type) { + case WAPI_HANDLE_MUTEX: return "mutex"; + case WAPI_HANDLE_NAMEDMUTEX: return "named mutex"; + default: + g_assert_not_reached (); + } } -static gboolean mutex_own (gpointer handle) +static gboolean +mutex_handle_own (gpointer handle, WapiHandleType type) { struct _WapiHandle_mutex *mutex_handle; - gboolean ok; - - ok = _wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX, - (gpointer *)&mutex_handle); - if (ok == FALSE) { - g_warning ("%s: error looking up mutex handle %p", __func__, - handle); - return(FALSE); + + if (!_wapi_lookup_handle (handle, type, (gpointer *)&mutex_handle)) { + g_warning ("%s: error looking up %s handle %p", __func__, mutex_handle_type_to_string (type), handle); + return FALSE; } + MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning %s handle %p, tid %p, recursion %u", + __func__, mutex_handle_type_to_string (type), handle, (gpointer) mutex_handle->tid, mutex_handle->recursion); + _wapi_thread_own_mutex (handle); - - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning mutex handle %p", __func__, handle); - _wapi_handle_set_signal_state (handle, FALSE, FALSE); - mutex_handle->tid = pthread_self (); mutex_handle->recursion++; - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p locked %d times by %ld", __func__, - handle, mutex_handle->recursion, mutex_handle->tid); + _wapi_handle_set_signal_state (handle, FALSE, FALSE); - return(TRUE); + return TRUE; } -static gboolean mutex_is_owned (gpointer handle) +static gboolean +mutex_handle_is_owned (gpointer handle, WapiHandleType type) { struct _WapiHandle_mutex *mutex_handle; - gboolean ok; - - ok=_wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX, - (gpointer *)&mutex_handle); - if(ok==FALSE) { - g_warning ("%s: error looking up mutex handle %p", __func__, - handle); - return(FALSE); + + if (!_wapi_lookup_handle (handle, type, (gpointer *)&mutex_handle)) { + g_warning ("%s: error looking up %s handle %p", __func__, mutex_handle_type_to_string (type), handle); + return FALSE; } - - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: testing ownership mutex handle %p", __func__, handle); - if (mutex_handle->recursion > 0 && pthread_equal (mutex_handle->tid, pthread_self ())) { - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p owned by %ld", __func__, - handle, pthread_self ()); + MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: testing ownership %s handle %p", + __func__, mutex_handle_type_to_string (type), handle); - return(TRUE); + 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__, mutex_handle_type_to_string (type), handle, (gpointer) pthread_self ()); + return TRUE; } else { - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p not owned by %ld, but locked %d times by %ld", __func__, - handle, pthread_self (), mutex_handle->recursion, mutex_handle->tid); - - return(FALSE); + MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s handle %p not owned by %p, but locked %d times by %p", + __func__, mutex_handle_type_to_string (type), handle, (gpointer) pthread_self (), mutex_handle->recursion, (gpointer) mutex_handle->tid); + return FALSE; } } -static void namedmutex_signal (gpointer handle) +static void mutex_signal(gpointer handle) { ReleaseMutex(handle); } -/* NB, always called with the shared handle lock held */ -static gboolean namedmutex_own (gpointer handle) +static gboolean mutex_own (gpointer handle) { - struct _WapiHandle_namedmutex *namedmutex_handle; - gboolean ok; - - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning named mutex handle %p", __func__, handle); - - ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX, - (gpointer *)&namedmutex_handle); - if (ok == FALSE) { - g_warning ("%s: error looking up named mutex handle %p", - __func__, handle); - return(FALSE); - } - - _wapi_thread_own_mutex (handle); - - namedmutex_handle->tid = pthread_self (); - namedmutex_handle->recursion++; - - _wapi_shared_handle_set_signal_state (handle, FALSE); - - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p locked %d times by %ld", __func__, - handle, namedmutex_handle->recursion, namedmutex_handle->tid); - - return(TRUE); + return mutex_handle_own (handle, WAPI_HANDLE_MUTEX); } -static gboolean namedmutex_is_owned (gpointer handle) +static gboolean mutex_is_owned (gpointer handle) { - struct _WapiHandle_namedmutex *namedmutex_handle; - gboolean ok; - - ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX, - (gpointer *)&namedmutex_handle); - if (ok == FALSE) { - g_warning ("%s: error looking up mutex handle %p", __func__, - handle); - return(FALSE); - } - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: testing ownership mutex handle %p", __func__, handle); + return mutex_handle_is_owned (handle, WAPI_HANDLE_MUTEX); +} - if (namedmutex_handle->recursion > 0 && pthread_equal (namedmutex_handle->tid, pthread_self ())) { - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p owned by %ld", __func__, - handle, pthread_self ()); +static void namedmutex_signal (gpointer handle) +{ + ReleaseMutex(handle); +} - return(TRUE); - } else { - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p not owned by %ld, but locked %d times by %ld", __func__, - handle, pthread_self (), namedmutex_handle->recursion, namedmutex_handle->tid); +/* NB, always called with the shared handle lock held */ +static gboolean namedmutex_own (gpointer handle) +{ + return mutex_handle_own (handle, WAPI_HANDLE_NAMEDMUTEX); +} - return(FALSE); - } +static gboolean namedmutex_is_owned (gpointer handle) +{ + return mutex_handle_is_owned (handle, WAPI_HANDLE_NAMEDMUTEX); } -/* The shared state is not locked when prewait methods are called */ -static void namedmutex_prewait (gpointer handle) +static void mutex_handle_prewait (gpointer handle, WapiHandleType 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 @@ -222,242 +170,198 @@ static void namedmutex_prewait (gpointer handle) * and assume that process exited abnormally and failed to * clean up. */ - struct _WapiHandle_namedmutex *namedmutex_handle; - gboolean ok; - - ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX, - (gpointer *)&namedmutex_handle); - if (ok == FALSE) { - g_warning ("%s: error looking up named mutex handle %p", - __func__, handle); + struct _WapiHandle_mutex *mutex_handle; + + if (!_wapi_lookup_handle (handle, type, (gpointer *)&mutex_handle)) { + g_warning ("%s: error looking up %s handle %p", + __func__, mutex_handle_type_to_string (type), handle); return; } - - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Checking ownership of named mutex handle %p", __func__, - handle); - if (namedmutex_handle->recursion == 0) { - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Named mutex handle %p not owned", __func__, - handle); - } else { - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Named mutex handle %p owned by this process", __func__, - handle); - } + MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: pre-waiting %s handle %p, owned? %s", + __func__, mutex_handle_type_to_string (type), handle, mutex_handle->recursion != 0 ? "true" : "false"); } -static void mutex_abandon (gpointer handle, pid_t pid, pthread_t tid) +/* The shared state is not locked when prewait methods are called */ +static void mutex_prewait (gpointer handle) { - struct _WapiHandle_mutex *mutex_handle; - gboolean ok; - int thr_ret; + mutex_handle_prewait (handle, WAPI_HANDLE_MUTEX); +} + +/* The shared state is not locked when prewait methods are called */ +static void namedmutex_prewait (gpointer handle) +{ + mutex_handle_prewait (handle, WAPI_HANDLE_NAMEDMUTEX); +} + +static void mutex_details (gpointer data) +{ + struct _WapiHandle_mutex *mut = (struct _WapiHandle_mutex *)data; - ok = _wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX, - (gpointer *)&mutex_handle); - if (ok == FALSE) { - g_warning ("%s: error looking up mutex handle %p", __func__, - handle); - return; - } +#ifdef PTHREAD_POINTER_ID + g_print ("own: %5p, count: %5u", mut->tid, mut->recursion); +#else + g_print ("own: %5ld, count: %5u", mut->tid, mut->recursion); +#endif +} - thr_ret = _wapi_handle_lock_handle (handle); - g_assert (thr_ret == 0); +static void namedmutex_details (gpointer data) +{ + struct _WapiHandle_namedmutex *namedmut = (struct _WapiHandle_namedmutex *)data; - if (pthread_equal (mutex_handle->tid, tid)) { - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Mutex handle %p abandoned!", __func__, - handle); +#ifdef PTHREAD_POINTER_ID + g_print ("own: %5p, count: %5u, name: \"%s\"", + namedmut->m.tid, namedmut->m.recursion, namedmut->sharedns.name); +#else + g_print ("own: %5ld, count: %5u, name: \"%s\"", + namedmut->m.tid, namedmut->m.recursion, namedmut->sharedns.name); +#endif +} - mutex_handle->recursion = 0; - mutex_handle->tid = 0; - - _wapi_handle_set_signal_state (handle, TRUE, FALSE); - } +static const gchar* mutex_typename (void) +{ + return "Mutex"; +} - thr_ret = _wapi_handle_unlock_handle (handle); - g_assert (thr_ret == 0); +static gsize mutex_typesize (void) +{ + return sizeof (struct _WapiHandle_mutex); } -static void namedmutex_abandon (gpointer handle, pid_t pid, pthread_t tid) +static const gchar* namedmutex_typename (void) { - struct _WapiHandle_namedmutex *mutex_handle; - gboolean ok; + return "N.Mutex"; +} + +static gsize namedmutex_typesize (void) +{ + return sizeof (struct _WapiHandle_namedmutex); +} + +/* When a thread exits, any mutexes it still holds need to be signalled. */ +void _wapi_mutex_abandon (gpointer handle, pid_t pid, pthread_t tid) +{ + WapiHandleType type; + struct _WapiHandle_mutex *mutex_handle; int thr_ret; - - ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX, - (gpointer *)&mutex_handle); - if (ok == FALSE) { - g_warning ("%s: error looking up named mutex handle %p", - __func__, handle); + + switch (type = _wapi_handle_type (handle)) { + case WAPI_HANDLE_MUTEX: + case WAPI_HANDLE_NAMEDMUTEX: + break; + default: + g_assert_not_reached (); + } + + if (!_wapi_lookup_handle (handle, type, (gpointer *)&mutex_handle)) { + g_warning ("%s: error looking up %s handle %p", + __func__, mutex_handle_type_to_string (type), handle); return; } - thr_ret = _wapi_handle_lock_shared_handles (); + MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: abandon %s handle %p", + __func__, mutex_handle_type_to_string (type), handle); + + thr_ret = _wapi_handle_lock_handle (handle); g_assert (thr_ret == 0); - - if (pthread_equal (mutex_handle->tid, tid)) { - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Mutex handle %p abandoned!", __func__, - handle); + if (pthread_equal (mutex_handle->tid, tid)) { mutex_handle->recursion = 0; mutex_handle->tid = 0; - - _wapi_shared_handle_set_signal_state (handle, TRUE); - } - _wapi_handle_unlock_shared_handles (); -} - -/* When a thread exits, any mutexes it still holds need to be - * signalled. This function must not be called with the shared handle - * lock held, as namedmutex_abandon () will try to acquire it - */ -void _wapi_mutex_abandon (gpointer data, pid_t pid, pthread_t tid) -{ - WapiHandleType type = _wapi_handle_type (data); + _wapi_handle_set_signal_state (handle, TRUE, FALSE); - if (type == WAPI_HANDLE_MUTEX) { - mutex_abandon (data, pid, tid); - } else if (type == WAPI_HANDLE_NAMEDMUTEX) { - namedmutex_abandon (data, pid, tid); - } else { - g_assert_not_reached (); + MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: abandoned %s handle %p", + __func__, mutex_handle_type_to_string (type), handle); } + + thr_ret = _wapi_handle_unlock_handle (handle); + g_assert (thr_ret == 0); } -static gpointer mutex_create (WapiSecurityAttributes *security G_GNUC_UNUSED, - gboolean owned) +static gpointer mutex_handle_create (struct _WapiHandle_mutex *mutex_handle, WapiHandleType type, gboolean owned) { - struct _WapiHandle_mutex mutex_handle = {0}; gpointer handle; int thr_ret; - - /* 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 - */ - SetLastError (ERROR_SUCCESS); - - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating unnamed mutex", __func__); - - handle = _wapi_handle_new (WAPI_HANDLE_MUTEX, &mutex_handle); + + mutex_handle->tid = 0; + mutex_handle->recursion = 0; + + handle = _wapi_handle_new (type, mutex_handle); if (handle == _WAPI_HANDLE_INVALID) { - g_warning ("%s: error creating mutex handle", __func__); + g_warning ("%s: error creating %s handle", + __func__, mutex_handle_type_to_string (type)); SetLastError (ERROR_GEN_FAILURE); - return(NULL); + return NULL; } thr_ret = _wapi_handle_lock_handle (handle); g_assert (thr_ret == 0); - - if(owned==TRUE) { - mutex_own (handle); - } else { + + if (owned) + mutex_handle_own (handle, type); + else _wapi_handle_set_signal_state (handle, TRUE, FALSE); - } - - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning mutex handle %p", __func__, handle); thr_ret = _wapi_handle_unlock_handle (handle); g_assert (thr_ret == 0); - - return(handle); + + MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created %s handle %p", + __func__, mutex_handle_type_to_string (type), handle); + + return handle; } -static gpointer namedmutex_create (WapiSecurityAttributes *security G_GNUC_UNUSED, gboolean owned, - const gunichar2 *name) +static gpointer mutex_create (gboolean owned) +{ + struct _WapiHandle_mutex mutex_handle; + MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle", + __func__, mutex_handle_type_to_string (WAPI_HANDLE_MUTEX)); + return mutex_handle_create (&mutex_handle, WAPI_HANDLE_MUTEX, owned); +} + +static gpointer namedmutex_create (gboolean owned, const gunichar2 *name) { - struct _WapiHandle_namedmutex namedmutex_handle = {{{0}}, 0}; gpointer handle; gchar *utf8_name; int thr_ret; - gpointer ret = NULL; - guint32 namelen; - gint32 offset; - /* w32 seems to guarantee that opening named objects can't - * race each other - */ + MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle", + __func__, mutex_handle_type_to_string (WAPI_HANDLE_NAMEDMUTEX)); + + /* w32 seems to guarantee that opening named objects can't race each other */ thr_ret = _wapi_namespace_lock (); g_assert (thr_ret == 0); - /* 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 - */ - SetLastError (ERROR_SUCCESS); - utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL); - - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating named mutex [%s]", __func__, utf8_name); - - offset = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDMUTEX, - utf8_name); - if (offset == -1) { - /* The name has already been used for a different - * object. - */ + + handle = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDMUTEX, utf8_name); + if (handle == _WAPI_HANDLE_INVALID) { + /* The name has already been used for a different object. */ + handle = NULL; SetLastError (ERROR_INVALID_HANDLE); - goto cleanup; - } else if (offset != 0) { - /* Not an error, but this is how the caller is - * informed that the mutex wasn't freshly created - */ + } else if (handle) { + /* Not an error, but this is how the caller is informed that the mutex wasn't freshly created */ SetLastError (ERROR_ALREADY_EXISTS); - } - /* Fall through to create the mutex handle. */ - if (offset == 0) { - /* A new named mutex, so create both the private and - * shared parts - */ - - if (strlen (utf8_name) < MAX_PATH) { - namelen = strlen (utf8_name); - } else { - namelen = MAX_PATH; - } - - memcpy (&namedmutex_handle.sharedns.name, utf8_name, namelen); - - handle = _wapi_handle_new (WAPI_HANDLE_NAMEDMUTEX, - &namedmutex_handle); + /* this is used as creating a new handle */ + _wapi_handle_ref (handle); } else { - /* A new reference to an existing named mutex, so just - * create the private part - */ - handle = _wapi_handle_new_from_offset (WAPI_HANDLE_NAMEDMUTEX, offset); - } - - if (handle == _WAPI_HANDLE_INVALID) { - g_warning ("%s: error creating mutex handle", __func__); - SetLastError (ERROR_GEN_FAILURE); - goto cleanup; - } - ret = handle; + /* A new named mutex */ + struct _WapiHandle_namedmutex namedmutex_handle; - if (offset == 0) { - /* Set the initial state, as this is a completely new - * handle - */ - thr_ret = _wapi_handle_lock_shared_handles (); - g_assert (thr_ret == 0); - - if (owned == TRUE) { - namedmutex_own (handle); - } else { - _wapi_shared_handle_set_signal_state (handle, TRUE); - } + strncpy (&namedmutex_handle.sharedns.name [0], utf8_name, MAX_PATH); + namedmutex_handle.sharedns.name [MAX_PATH] = '\0'; - _wapi_handle_unlock_shared_handles (); + handle = mutex_handle_create ((struct _WapiHandle_mutex*) &namedmutex_handle, WAPI_HANDLE_NAMEDMUTEX, owned); } - - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning mutex handle %p", __func__, handle); -cleanup: g_free (utf8_name); - _wapi_namespace_unlock (NULL); - - return(ret); + thr_ret = _wapi_namespace_unlock (NULL); + g_assert (thr_ret == 0); + + return handle; } /** @@ -479,139 +383,87 @@ cleanup: * * Return value: A new handle, or %NULL on error. */ -gpointer CreateMutex(WapiSecurityAttributes *security G_GNUC_UNUSED, gboolean owned, - const gunichar2 *name) +gpointer CreateMutex(WapiSecurityAttributes *security G_GNUC_UNUSED, gboolean owned, const gunichar2 *name) { - mono_once (&mutex_ops_once, mutex_ops_init); + /* 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 */ + SetLastError (ERROR_SUCCESS); - if (name == NULL) { - return(mutex_create (security, owned)); - } else { - return(namedmutex_create (security, owned, name)); - } + return name ? namedmutex_create (owned, name) : mutex_create (owned); } -static gboolean mutex_release (gpointer handle) +/** + * ReleaseMutex: + * @handle: The mutex handle. + * + * Releases ownership if the mutex handle @handle. + * + * Return value: %TRUE on success, %FALSE otherwise. This function + * fails if the calling thread does not own the mutex @handle. + */ +gboolean ReleaseMutex(gpointer handle) { + WapiHandleType type; struct _WapiHandle_mutex *mutex_handle; - gboolean ok; - pthread_t tid = pthread_self (); + pthread_t tid; int thr_ret; - gboolean ret = FALSE; - - ok = _wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX, - (gpointer *)&mutex_handle); - if (ok == FALSE) { - g_warning ("%s: error looking up mutex handle %p", __func__, - handle); - return(FALSE); - } - - thr_ret = _wapi_handle_lock_handle (handle); - g_assert (thr_ret == 0); - - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Releasing mutex handle %p", __func__, handle); + gboolean ret; - if (!pthread_equal (mutex_handle->tid, tid)) { - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: We don't own mutex handle %p (owned by %ld, me %ld)", __func__, - handle, mutex_handle->tid, tid); - - goto cleanup; + if (handle == NULL) { + SetLastError (ERROR_INVALID_HANDLE); + return FALSE; } - ret = TRUE; - - /* OK, we own this mutex */ - mutex_handle->recursion--; - - if(mutex_handle->recursion==0) { - _wapi_thread_disown_mutex (handle); - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Unlocking mutex handle %p", __func__, handle); - - mutex_handle->tid=0; - _wapi_handle_set_signal_state (handle, TRUE, FALSE); + switch (type = _wapi_handle_type (handle)) { + case WAPI_HANDLE_MUTEX: + case WAPI_HANDLE_NAMEDMUTEX: + break; + default: + SetLastError (ERROR_INVALID_HANDLE); + return FALSE; } -cleanup: - thr_ret = _wapi_handle_unlock_handle (handle); - g_assert (thr_ret == 0); - - return(ret); -} - -static gboolean namedmutex_release (gpointer handle) -{ - struct _WapiHandle_namedmutex *mutex_handle; - gboolean ok; - pthread_t tid = pthread_self (); - int thr_ret; - gboolean ret = FALSE; - - ok=_wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX, - (gpointer *)&mutex_handle); - if(ok==FALSE) { - g_warning ("%s: error looking up named mutex handle %p", - __func__, handle); - return(FALSE); + if (!_wapi_lookup_handle (handle, type, (gpointer *)&mutex_handle)) { + g_warning ("%s: error looking up %s handle %p", + __func__, mutex_handle_type_to_string (type), handle); + return FALSE; } - thr_ret = _wapi_handle_lock_shared_handles (); + MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: releasing %s handle %p", + __func__, mutex_handle_type_to_string (type), handle); + + thr_ret = _wapi_handle_lock_handle (handle); g_assert (thr_ret == 0); - - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Releasing mutex handle %p", __func__, handle); + + tid = pthread_self (); if (!pthread_equal (mutex_handle->tid, tid)) { - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: We don't own mutex handle %p (owned by %ld, me %ld)", __func__, - handle, mutex_handle->tid, tid); + ret = FALSE; - goto cleanup; - } - ret = TRUE; - - /* OK, we own this mutex */ - mutex_handle->recursion--; - - if(mutex_handle->recursion==0) { - _wapi_thread_disown_mutex (handle); + MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: we don't own %s handle %p (owned by %ld, me %ld)", + __func__, mutex_handle_type_to_string (type), handle, mutex_handle->tid, tid); + } else { + ret = TRUE; - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Unlocking mutex handle %p", __func__, handle); + /* OK, we own this mutex */ + mutex_handle->recursion--; - mutex_handle->tid=0; - _wapi_shared_handle_set_signal_state (handle, TRUE); - } + if (mutex_handle->recursion == 0) { + _wapi_thread_disown_mutex (handle); -cleanup: - _wapi_handle_unlock_shared_handles (); - - return(ret); -} - -/** - * ReleaseMutex: - * @handle: The mutex handle. - * - * Releases ownership if the mutex handle @handle. - * - * Return value: %TRUE on success, %FALSE otherwise. This function - * fails if the calling thread does not own the mutex @handle. - */ -gboolean ReleaseMutex(gpointer handle) -{ - WapiHandleType type; + MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking %s handle %p", + __func__, mutex_handle_type_to_string (type), handle); - if (handle == NULL) { - SetLastError (ERROR_INVALID_HANDLE); - return(FALSE); - } - - type = _wapi_handle_type (handle); - - if (mutex_ops[type].release == NULL) { - SetLastError (ERROR_INVALID_HANDLE); - return(FALSE); + mutex_handle->tid = 0; + _wapi_handle_set_signal_state (handle, TRUE, FALSE); + } } - - return(mutex_ops[type].release (handle)); + + thr_ret = _wapi_handle_unlock_handle (handle); + g_assert (thr_ret == 0); + + return ret; } gpointer OpenMutex (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, const gunichar2 *name) @@ -619,10 +471,6 @@ gpointer OpenMutex (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED gpointer handle; gchar *utf8_name; int thr_ret; - gpointer ret = NULL; - gint32 offset; - - mono_once (&mutex_ops_once, mutex_ops_init); /* w32 seems to guarantee that opening named objects can't * race each other @@ -634,32 +482,20 @@ gpointer OpenMutex (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening named mutex [%s]", __func__, utf8_name); - offset = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDMUTEX, + handle = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDMUTEX, utf8_name); - if (offset == -1) { + if (handle == _WAPI_HANDLE_INVALID) { /* The name has already been used for a different * object. */ SetLastError (ERROR_INVALID_HANDLE); goto cleanup; - } else if (offset == 0) { + } else if (!handle) { /* This name doesn't exist */ SetLastError (ERROR_FILE_NOT_FOUND); /* yes, really */ goto cleanup; } - /* A new reference to an existing named mutex, so just create - * the private part - */ - handle = _wapi_handle_new_from_offset (WAPI_HANDLE_NAMEDMUTEX, offset); - - if (handle == _WAPI_HANDLE_INVALID) { - g_warning ("%s: error opening named mutex handle", __func__); - SetLastError (ERROR_GEN_FAILURE); - goto cleanup; - } - ret = handle; - MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning named mutex handle %p", __func__, handle); cleanup: @@ -667,5 +503,5 @@ cleanup: _wapi_namespace_unlock (NULL); - return(ret); + return handle; }