[io-layer] Extract Mutex, Semaphore and Event (#3553)
authorLudovic Henry <ludovic@xamarin.com>
Tue, 13 Sep 2016 21:40:58 +0000 (23:40 +0200)
committerGitHub <noreply@github.com>
Tue, 13 Sep 2016 21:40:58 +0000 (23:40 +0200)
* [metadata] Move mutex managed support to seperate file

* [mutex] Extract CreateMutex

* [mutex] Extract ReleaseMutex

* [mutex] Extract OpenMutex

* [mutex] Extract wapi_mutex_abandon

* [mutex] Extract MonoW32HandleOps for mutex and named mutex

* [io-layer] Extract wapi_search_handle_namespace

* [metadata] Move semaphore managed support to seperate file

* [semaphore] Move _WapiHandle_sem and _WapiHandle_namedsem to semaphores.h

* [semaphore] Extract CreateSemaphore

* [semaphore] Extract ReleaseSemaphore

* [semaphore] Extract OpenSemaphore

* [semaphore] Extract MonoW32HandleOps

* [metadata] Move event managed support to seperate file

* [event] Extract CreateEvent

* [event] Remove dead code PulseEvent

* [event] Extract SetEvent

* [event] Extract ResetEvent

* [event] Extract OpenHandle

* [event] Extract MonoW32HandleOps

* [w32handle] Extract namespace locking

* [io-layer] Inline only use of wapi_shm_sem_lock/wapi_shm_sem_unlock

40 files changed:
mono/io-layer/Makefile.am
mono/io-layer/event-private.h [deleted file]
mono/io-layer/events.c [deleted file]
mono/io-layer/events.h [deleted file]
mono/io-layer/io.c
mono/io-layer/mutex-private.h [deleted file]
mono/io-layer/mutexes.c [deleted file]
mono/io-layer/mutexes.h [deleted file]
mono/io-layer/semaphore-private.h [deleted file]
mono/io-layer/semaphores.c [deleted file]
mono/io-layer/semaphores.h [deleted file]
mono/io-layer/shared.c [deleted file]
mono/io-layer/shared.h [deleted file]
mono/io-layer/wapi-private.h
mono/io-layer/wapi-remap.h
mono/io-layer/wapi.c
mono/io-layer/wapi.h
mono/metadata/Makefile.am
mono/metadata/domain.c
mono/metadata/icall.c
mono/metadata/monitor.c
mono/metadata/object.c
mono/metadata/threadpool-ms.c
mono/metadata/threads-types.h
mono/metadata/threads.c
mono/metadata/w32event-unix.c [new file with mode: 0644]
mono/metadata/w32event-win32.c [new file with mode: 0644]
mono/metadata/w32event.h [new file with mode: 0644]
mono/metadata/w32handle-namespace.c [new file with mode: 0644]
mono/metadata/w32handle-namespace.h [new file with mode: 0644]
mono/metadata/w32mutex-unix.c [new file with mode: 0644]
mono/metadata/w32mutex-utils.h [new file with mode: 0644]
mono/metadata/w32mutex-win32.c [new file with mode: 0644]
mono/metadata/w32mutex.h [new file with mode: 0644]
mono/metadata/w32semaphore-unix.c [new file with mode: 0644]
mono/metadata/w32semaphore-win32.c [new file with mode: 0644]
mono/metadata/w32semaphore.h [new file with mode: 0644]
mono/utils/mono-threads-posix.c
msvc/libmonoruntime.vcxproj
msvc/libmonoruntime.vcxproj.filters

index 0eb885e055e4a843868fbcc00a1f0600a99827a1..dfb60a16c827e5db876948193eef80196708b887 100644 (file)
@@ -14,17 +14,14 @@ OTHER_H = \
        access.h        \
        context.h       \
        error.h         \
-       events.h        \
        io.h            \
        io-trace.h      \
        io-layer.h      \
        io-portability.h        \
        macros.h        \
        messages.h      \
-       mutexes.h       \
        processes.h     \
        security.h      \
-       semaphores.h    \
        sockets.h       \
        status.h        \
        timefuncs.h     \
@@ -41,9 +38,6 @@ OTHER_SRC = \
        context.h               \
        error.c                 \
        error.h                 \
-       events.c                \
-       events.h                \
-       event-private.h         \
        io.c                    \
        io.h                    \
        io-portability.c        \
@@ -54,20 +48,12 @@ OTHER_SRC = \
        macros.h                \
        messages.c              \
        messages.h              \
-       mutexes.c               \
-       mutexes.h               \
-       mutex-private.h         \
        posix.c                 \
        processes.c             \
        processes.h             \
        process-private.h       \
        security.c              \
        security.h              \
-       semaphores.c            \
-       semaphores.h            \
-       semaphore-private.h     \
-       shared.c                \
-       shared.h                \
        sockets.c               \
        sockets.h               \
        socket-private.h        \
diff --git a/mono/io-layer/event-private.h b/mono/io-layer/event-private.h
deleted file mode 100644 (file)
index 07b35e0..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * event-private.h:  Private definitions for event handles
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#ifndef _WAPI_EVENT_PRIVATE_H_
-#define _WAPI_EVENT_PRIVATE_H_
-
-#include <config.h>
-#include <glib.h>
-#include <pthread.h>
-
-#include "wapi-private.h"
-
-struct _WapiHandle_event
-{
-       gboolean manual;
-       guint32 set_count;
-};
-
-struct _WapiHandle_namedevent
-{
-       struct _WapiHandle_event e;
-       WapiSharedNamespace sharedns;
-};
-
-void
-_wapi_event_init (void);
-
-#endif /* _WAPI_EVENT_PRIVATE_H_ */
diff --git a/mono/io-layer/events.c b/mono/io-layer/events.c
deleted file mode 100644 (file)
index 8e3fa4a..0000000
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * events.c:  Event handles
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#include <config.h>
-#include <glib.h>
-#include <pthread.h>
-#include <string.h>
-
-#include <mono/io-layer/wapi.h>
-#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/event-private.h>
-#include <mono/io-layer/io-trace.h>
-#include <mono/utils/mono-once.h>
-#include <mono/utils/mono-logger-internals.h>
-#include <mono/utils/w32handle.h>
-
-static void event_signal(gpointer handle);
-static gboolean event_own (gpointer handle);
-static void event_details (gpointer data);
-static const gchar* event_typename (void);
-static gsize event_typesize (void);
-
-static void namedevent_signal (gpointer handle);
-static gboolean namedevent_own (gpointer handle);
-static void namedevent_details (gpointer data);
-static const gchar* namedevent_typename (void);
-static gsize namedevent_typesize (void);
-
-static MonoW32HandleOps _wapi_event_ops = {
-       NULL,                   /* close */
-       event_signal,           /* signal */
-       event_own,              /* own */
-       NULL,                   /* is_owned */
-       NULL,                   /* special_wait */
-       NULL,                   /* prewait */
-       event_details,  /* details */
-       event_typename, /* typename */
-       event_typesize, /* typesize */
-};
-
-static MonoW32HandleOps _wapi_namedevent_ops = {
-       NULL,                   /* close */
-       namedevent_signal,      /* signal */
-       namedevent_own,         /* own */
-       NULL,                   /* is_owned */
-       NULL,                   /* special_wait */
-       NULL,                   /* prewait */
-       namedevent_details,     /* details */
-       namedevent_typename, /* typename */
-       namedevent_typesize, /* typesize */
-};
-
-void
-_wapi_event_init (void)
-{
-       mono_w32handle_register_ops (MONO_W32HANDLE_EVENT,      &_wapi_event_ops);
-       mono_w32handle_register_ops (MONO_W32HANDLE_NAMEDEVENT, &_wapi_namedevent_ops);
-
-       mono_w32handle_register_capabilities (MONO_W32HANDLE_EVENT,
-               (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
-       mono_w32handle_register_capabilities (MONO_W32HANDLE_NAMEDEVENT,
-               (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
-}
-
-static const char* event_handle_type_to_string (MonoW32HandleType type)
-{
-       switch (type) {
-       case MONO_W32HANDLE_EVENT: return "event";
-       case MONO_W32HANDLE_NAMEDEVENT: return "named event";
-       default:
-               g_assert_not_reached ();
-       }
-}
-
-static gboolean event_handle_own (gpointer handle, MonoW32HandleType type)
-{
-       struct _WapiHandle_event *event_handle;
-       gboolean ok;
-
-       ok = mono_w32handle_lookup (handle, type, (gpointer *)&event_handle);
-       if (!ok) {
-               g_warning ("%s: error looking up %s handle %p",
-                       __func__, event_handle_type_to_string (type), handle);
-               return FALSE;
-       }
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning %s handle %p",
-               __func__, event_handle_type_to_string (type), handle);
-
-       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, FALSE, FALSE);
-       }
-
-       return TRUE;
-}
-
-static void event_signal(gpointer handle)
-{
-       SetEvent(handle);
-}
-
-static gboolean event_own (gpointer handle)
-{
-       return event_handle_own (handle, MONO_W32HANDLE_EVENT);
-}
-
-static void namedevent_signal (gpointer handle)
-{
-       SetEvent (handle);
-}
-
-/* NB, always called with the shared handle lock held */
-static gboolean namedevent_own (gpointer handle)
-{
-       return event_handle_own (handle, MONO_W32HANDLE_NAMEDEVENT);
-}
-
-static void event_details (gpointer data)
-{
-       struct _WapiHandle_event *event = (struct _WapiHandle_event *)data;
-       g_print ("manual: %s, set_count: %d",
-               event->manual ? "TRUE" : "FALSE", event->set_count);
-}
-
-static void namedevent_details (gpointer data)
-{
-       struct _WapiHandle_namedevent *namedevent = (struct _WapiHandle_namedevent *)data;
-       g_print ("manual: %s, set_count: %d, name: \"%s\"",
-               namedevent->e.manual ? "TRUE" : "FALSE", namedevent->e.set_count, namedevent->sharedns.name);
-}
-
-static const gchar* event_typename (void)
-{
-       return "Event";
-}
-
-static gsize event_typesize (void)
-{
-       return sizeof (struct _WapiHandle_event);
-}
-
-static const gchar* namedevent_typename (void)
-{
-       return "N.Event";
-}
-
-static gsize namedevent_typesize (void)
-{
-       return sizeof (struct _WapiHandle_namedevent);
-}
-
-static gpointer event_handle_create (struct _WapiHandle_event *event_handle, MonoW32HandleType type, gboolean manual, gboolean initial)
-{
-       gpointer handle;
-       int thr_ret;
-
-       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__, event_handle_type_to_string (type));
-               SetLastError (ERROR_GEN_FAILURE);
-               return NULL;
-       }
-
-       thr_ret = mono_w32handle_lock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       if (initial)
-               mono_w32handle_set_signal_state (handle, TRUE, FALSE);
-
-       thr_ret = mono_w32handle_unlock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created %s handle %p",
-               __func__, event_handle_type_to_string (type), handle);
-
-       return handle;
-}
-
-static gpointer event_create (gboolean manual, gboolean initial)
-{
-       struct _WapiHandle_event event_handle;
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle",
-               __func__, event_handle_type_to_string (MONO_W32HANDLE_EVENT));
-       return event_handle_create (&event_handle, MONO_W32HANDLE_EVENT, manual, initial);
-}
-
-static gpointer namedevent_create (gboolean manual, gboolean initial, const gunichar2 *name G_GNUC_UNUSED)
-{
-       gpointer handle;
-       gchar *utf8_name;
-       int thr_ret;
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle",
-               __func__, event_handle_type_to_string (MONO_W32HANDLE_NAMEDEVENT));
-
-       /* w32 seems to guarantee that opening named objects can't race each other */
-       thr_ret = _wapi_namespace_lock ();
-       g_assert (thr_ret == 0);
-
-       utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
-
-       handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDEVENT, 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 event wasn't freshly created */
-               SetLastError (ERROR_ALREADY_EXISTS);
-
-               /* this is used as creating a new handle */
-               mono_w32handle_ref (handle);
-       } else {
-               /* A new named event */
-               struct _WapiHandle_namedevent namedevent_handle;
-
-               strncpy (&namedevent_handle.sharedns.name [0], utf8_name, MAX_PATH);
-               namedevent_handle.sharedns.name [MAX_PATH] = '\0';
-
-               handle = event_handle_create ((struct _WapiHandle_event*) &namedevent_handle, MONO_W32HANDLE_NAMEDEVENT, manual, initial);
-       }
-
-       g_free (utf8_name);
-
-       thr_ret = _wapi_namespace_unlock (NULL);
-       g_assert (thr_ret == 0);
-
-       return handle;
-}
-
-
-/**
- * CreateEvent:
- * @security: Ignored for now.
- * @manual: Specifies whether the new event handle has manual or auto
- * reset behaviour.
- * @initial: Specifies whether the new event handle is initially
- * signalled or not.
- * @name:Pointer to a string specifying the name of this name, or
- * %NULL.  Currently ignored.
- *
- * Creates a new event handle.
- *
- * An event handle is signalled with SetEvent().  If the new handle is
- * a manual reset event handle, it remains signalled until it is reset
- * with ResetEvent().  An auto reset event remains signalled until a
- * single thread has waited for it, at which time the event handle is
- * automatically reset to unsignalled.
- *
- * Return value: A new handle, or %NULL on error.
- */
-gpointer CreateEvent(WapiSecurityAttributes *security G_GNUC_UNUSED,
-                    gboolean manual, gboolean initial,
-                    const gunichar2 *name G_GNUC_UNUSED)
-{
-       /* Need to blow away any old errors here, because code tests
-        * for ERROR_ALREADY_EXISTS on success (!) to see if an event
-        * was freshly created
-        */
-       SetLastError (ERROR_SUCCESS);
-
-       return name ? namedevent_create (manual, initial, name) : event_create (manual, initial);
-}
-
-/**
- * PulseEvent:
- * @handle: The event handle.
- *
- * Sets the event handle @handle to the signalled state, and then
- * resets it to unsignalled after informing any waiting threads.
- *
- * If @handle is a manual reset event, all waiting threads that can be
- * released immediately are released.  @handle is then reset.  If
- * @handle is an auto reset event, one waiting thread is released even
- * if multiple threads are waiting.
- *
- * Return value: %TRUE on success, %FALSE otherwise.  (Currently only
- * ever returns %TRUE).
- */
-gboolean PulseEvent(gpointer handle)
-{
-       MonoW32HandleType type;
-       struct _WapiHandle_event *event_handle;
-       int thr_ret;
-
-       if (handle == NULL) {
-               SetLastError (ERROR_INVALID_HANDLE);
-               return(FALSE);
-       }
-
-       switch (type = mono_w32handle_get_type (handle)) {
-       case MONO_W32HANDLE_EVENT:
-       case MONO_W32HANDLE_NAMEDEVENT:
-               break;
-       default:
-               SetLastError (ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-
-       if (!mono_w32handle_lookup (handle, type, (gpointer *)&event_handle)) {
-               g_warning ("%s: error looking up %s handle %p",
-                       __func__, event_handle_type_to_string (type), handle);
-               return FALSE;
-       }
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: pulsing %s handle %p",
-               __func__, event_handle_type_to_string (type), handle);
-
-       thr_ret = mono_w32handle_lock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       if (!event_handle->manual) {
-               event_handle->set_count = 1;
-               mono_w32handle_set_signal_state (handle, TRUE, FALSE);
-       } else {
-               mono_w32handle_set_signal_state (handle, TRUE, TRUE);
-
-               thr_ret = mono_w32handle_unlock_handle (handle);
-               g_assert (thr_ret == 0);
-
-               /* For a manual-reset event, we're about to try and get the handle
-                * lock again, so give other threads a chance */
-               sched_yield ();
-
-               /* Reset the handle signal state */
-
-               /* I'm not sure whether or not we need a barrier here to make sure
-                * that all threads waiting on the event have proceeded. Currently
-                * we rely on broadcasting a condition. */
-
-               thr_ret = mono_w32handle_lock_handle (handle);
-               g_assert (thr_ret == 0);
-
-               mono_w32handle_set_signal_state (handle, FALSE, FALSE);
-       }
-
-       thr_ret = mono_w32handle_unlock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       return TRUE;
-}
-
-/**
- * ResetEvent:
- * @handle: The event handle.
- *
- * Resets the event handle @handle to the unsignalled state.
- *
- * Return value: %TRUE on success, %FALSE otherwise.  (Currently only
- * ever returns %TRUE).
- */
-gboolean ResetEvent(gpointer handle)
-{
-       MonoW32HandleType type;
-       struct _WapiHandle_event *event_handle;
-       int thr_ret;
-
-       SetLastError (ERROR_SUCCESS);
-       
-       if (handle == NULL) {
-               SetLastError (ERROR_INVALID_HANDLE);
-               return(FALSE);
-       }
-       
-       switch (type = mono_w32handle_get_type (handle)) {
-       case MONO_W32HANDLE_EVENT:
-       case MONO_W32HANDLE_NAMEDEVENT:
-               break;
-       default:
-               SetLastError (ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-
-       if (!mono_w32handle_lookup (handle, type, (gpointer *)&event_handle)) {
-               g_warning ("%s: error looking up %s handle %p",
-                       __func__, event_handle_type_to_string (type), handle);
-               return FALSE;
-       }
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: resetting %s handle %p",
-               __func__, event_handle_type_to_string (type), handle);
-
-       thr_ret = mono_w32handle_lock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       if (!mono_w32handle_issignalled (handle)) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: no need to reset %s handle %p",
-                       __func__, event_handle_type_to_string (type), handle);
-       } else {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: obtained write lock on %s handle %p",
-                       __func__, event_handle_type_to_string (type), handle);
-
-               mono_w32handle_set_signal_state (handle, FALSE, FALSE);
-       }
-
-       event_handle->set_count = 0;
-
-       thr_ret = mono_w32handle_unlock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       return TRUE;
-}
-
-/**
- * SetEvent:
- * @handle: The event handle
- *
- * Sets the event handle @handle to the signalled state.
- *
- * If @handle is a manual reset event, it remains signalled until it
- * is reset with ResetEvent().  An auto reset event remains signalled
- * until a single thread has waited for it, at which time @handle is
- * automatically reset to unsignalled.
- *
- * Return value: %TRUE on success, %FALSE otherwise.  (Currently only
- * ever returns %TRUE).
- */
-gboolean SetEvent(gpointer handle)
-{
-       MonoW32HandleType type;
-       struct _WapiHandle_event *event_handle;
-       int thr_ret;
-       
-       if (handle == NULL) {
-               SetLastError (ERROR_INVALID_HANDLE);
-               return(FALSE);
-       }
-       
-       switch (type = mono_w32handle_get_type (handle)) {
-       case MONO_W32HANDLE_EVENT:
-       case MONO_W32HANDLE_NAMEDEVENT:
-               break;
-       default:
-               SetLastError (ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-
-       if (!mono_w32handle_lookup (handle, type, (gpointer *)&event_handle)) {
-               g_warning ("%s: error looking up %s handle %p",
-                       __func__, event_handle_type_to_string (type), handle);
-               return FALSE;
-       }
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: setting %s handle %p",
-               __func__, event_handle_type_to_string (type), handle);
-
-       thr_ret = mono_w32handle_lock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       if (!event_handle->manual) {
-               event_handle->set_count = 1;
-               mono_w32handle_set_signal_state (handle, TRUE, FALSE);
-       } else {
-               mono_w32handle_set_signal_state (handle, TRUE, TRUE);
-       }
-
-       thr_ret = mono_w32handle_unlock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       return TRUE;
-}
-
-gpointer OpenEvent (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, const gunichar2 *name)
-{
-       gpointer handle;
-       gchar *utf8_name;
-       int thr_ret;
-
-       /* w32 seems to guarantee that opening named objects can't
-        * race each other
-        */
-       thr_ret = _wapi_namespace_lock ();
-       g_assert (thr_ret == 0);
-
-       utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
-       
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening named event [%s]", __func__, utf8_name);
-       
-       handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDEVENT,
-                                               utf8_name);
-       if (handle == INVALID_HANDLE_VALUE) {
-               /* The name has already been used for a different
-                * object.
-                */
-               SetLastError (ERROR_INVALID_HANDLE);
-               goto cleanup;
-       } else if (!handle) {
-               /* This name doesn't exist */
-               SetLastError (ERROR_FILE_NOT_FOUND);    /* yes, really */
-               goto cleanup;
-       }
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning named event handle %p", __func__, handle);
-
-cleanup:
-       g_free (utf8_name);
-
-       _wapi_namespace_unlock (NULL);
-       
-       return handle;
-
-}
diff --git a/mono/io-layer/events.h b/mono/io-layer/events.h
deleted file mode 100644 (file)
index 577f57b..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * events.h:  Event handles
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#ifndef _WAPI_EVENTS_H_
-#define _WAPI_EVENTS_H_
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-extern gpointer CreateEvent (WapiSecurityAttributes *security, gboolean manual,
-                            gboolean initial, const gunichar2 *name);
-extern gboolean PulseEvent (gpointer handle);
-extern gboolean ResetEvent (gpointer handle);
-extern gboolean SetEvent (gpointer handle);
-extern gpointer OpenEvent (guint32 access, gboolean inherit,
-                          const gunichar2 *name);
-
-G_END_DECLS
-
-#endif /* _WAPI_EVENTS_H_ */
index baf297ae7450123d50878ba4869eaf1df5e66ea0..661067dc7b27b1461c9ee63858da5c519e0256f2 100644 (file)
  * 4MB array.
  */
 static GHashTable *file_share_hash;
-static mono_mutex_t file_share_hash_mutex;
-
-#define file_share_hash_lock() mono_os_mutex_lock (&file_share_hash_mutex)
-#define file_share_hash_unlock() mono_os_mutex_unlock (&file_share_hash_mutex)
+static mono_mutex_t file_share_mutex;
 
 static void
 _wapi_handle_share_release (_WapiFileShare *share_info)
 {
-       int thr_ret;
+       /* Prevent new entries racing with us */
+       mono_os_mutex_lock (&file_share_mutex);
 
        g_assert (share_info->handle_refs > 0);
-       
-       /* Prevent new entries racing with us */
-       thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
-       g_assert(thr_ret == 0);
+       share_info->handle_refs -= 1;
 
-       if (InterlockedDecrement ((gint32 *)&share_info->handle_refs) == 0) {
-               file_share_hash_lock ();
+       if (share_info->handle_refs == 0)
                g_hash_table_remove (file_share_hash, share_info);
-               file_share_hash_unlock ();
-       }
 
-       thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
-       g_assert (thr_ret == 0);
+       mono_os_mutex_unlock (&file_share_mutex);
 }
 
 static gint
@@ -101,12 +92,10 @@ _wapi_handle_get_or_set_share (guint64 device, guint64 inode, guint32 new_sharem
        guint32 *old_sharemode, guint32 *old_access, struct _WapiFileShare **share_info)
 {
        struct _WapiFileShare *file_share;
-       int thr_ret;
        gboolean exists = FALSE;
 
        /* Prevent new entries racing with us */
-       thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
-       g_assert (thr_ret == 0);
+       mono_os_mutex_lock (&file_share_mutex);
 
        _WapiFileShare tmp;
 
@@ -115,23 +104,21 @@ _wapi_handle_get_or_set_share (guint64 device, guint64 inode, guint32 new_sharem
         * info. This is needed even if SHM is disabled, to track sharing inside
         * the current process.
         */
-       if (!file_share_hash) {
+       if (!file_share_hash)
                file_share_hash = g_hash_table_new_full (wapi_share_info_hash, wapi_share_info_equal, NULL, g_free);
-               mono_os_mutex_init_recursive (&file_share_hash_mutex);
-       }
 
        tmp.device = device;
        tmp.inode = inode;
 
-       file_share_hash_lock ();
-
        file_share = (_WapiFileShare *)g_hash_table_lookup (file_share_hash, &tmp);
        if (file_share) {
                *old_sharemode = file_share->sharemode;
                *old_access = file_share->access;
                *share_info = file_share;
 
-               InterlockedIncrement ((gint32 *)&file_share->handle_refs);
+               g_assert (file_share->handle_refs > 0);
+               file_share->handle_refs += 1;
+
                exists = TRUE;
        } else {
                file_share = g_new0 (_WapiFileShare, 1);
@@ -147,10 +134,7 @@ _wapi_handle_get_or_set_share (guint64 device, guint64 inode, guint32 new_sharem
                g_hash_table_insert (file_share_hash, file_share, file_share);
        }
 
-       file_share_hash_unlock ();
-       
-       thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
-       g_assert (thr_ret == 0);
+       mono_os_mutex_unlock (&file_share_mutex);
 
        return(exists);
 }
@@ -4435,6 +4419,7 @@ void
 _wapi_io_init (void)
 {
        mono_os_mutex_init (&stdhandle_mutex);
+       mono_os_mutex_init (&file_share_mutex);
 
        mono_w32handle_register_ops (MONO_W32HANDLE_FILE,    &_wapi_file_ops);
        mono_w32handle_register_ops (MONO_W32HANDLE_CONSOLE, &_wapi_console_ops);
@@ -4453,8 +4438,8 @@ _wapi_io_init (void)
 void
 _wapi_io_cleanup (void)
 {
-       if (file_share_hash) {
+       mono_os_mutex_destroy (&file_share_mutex);
+
+       if (file_share_hash)
                g_hash_table_destroy (file_share_hash);
-               mono_os_mutex_destroy (&file_share_hash_mutex);
-       }
 }
diff --git a/mono/io-layer/mutex-private.h b/mono/io-layer/mutex-private.h
deleted file mode 100644 (file)
index 50e5b14..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * mutex-private.h:  Private definitions for mutex handles
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#ifndef _WAPI_MUTEX_PRIVATE_H_
-#define _WAPI_MUTEX_PRIVATE_H_
-
-#include <config.h>
-#include <glib.h>
-#include <pthread.h>
-#include <sys/types.h>
-
-#include "wapi-private.h"
-
-struct _WapiHandle_mutex
-{
-       pthread_t tid;
-       guint32 recursion;
-};
-
-struct _WapiHandle_namedmutex 
-{
-       struct _WapiHandle_mutex m;
-       WapiSharedNamespace sharedns;
-};
-
-void
-_wapi_mutex_init (void);
-
-#endif /* _WAPI_MUTEX_PRIVATE_H_ */
diff --git a/mono/io-layer/mutexes.c b/mono/io-layer/mutexes.c
deleted file mode 100644 (file)
index dbfe8b1..0000000
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
- * mutexes.c:  Mutex handles
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002-2006 Ximian, Inc.
- */
-
-#include <config.h>
-#include <glib.h>
-#include <pthread.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <mono/io-layer/wapi.h>
-#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/mutex-private.h>
-#include <mono/io-layer/io-trace.h>
-#include <mono/utils/mono-once.h>
-#include <mono/utils/mono-logger-internals.h>
-#include <mono/utils/w32handle.h>
-
-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);
-
-static MonoW32HandleOps _wapi_mutex_ops = {
-       NULL,                   /* close */
-       mutex_signal,           /* signal */
-       mutex_own,              /* own */
-       mutex_is_owned,         /* is_owned */
-       NULL,                   /* special_wait */
-       mutex_prewait,                  /* prewait */
-       mutex_details,  /* details */
-       mutex_typename, /* typename */
-       mutex_typesize, /* typesize */
-};
-
-static MonoW32HandleOps _wapi_namedmutex_ops = {
-       NULL,                   /* close */
-       namedmutex_signal,      /* signal */
-       namedmutex_own,         /* own */
-       namedmutex_is_owned,    /* is_owned */
-       NULL,                   /* special_wait */
-       namedmutex_prewait,     /* prewait */
-       namedmutex_details,     /* details */
-       namedmutex_typename,    /* typename */
-       namedmutex_typesize,    /* typesize */
-};
-
-void
-_wapi_mutex_init (void)
-{
-       mono_w32handle_register_ops (MONO_W32HANDLE_MUTEX,      &_wapi_mutex_ops);
-       mono_w32handle_register_ops (MONO_W32HANDLE_NAMEDMUTEX, &_wapi_namedmutex_ops);
-
-       mono_w32handle_register_capabilities (MONO_W32HANDLE_MUTEX,
-               (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL | MONO_W32HANDLE_CAP_OWN));
-       mono_w32handle_register_capabilities (MONO_W32HANDLE_NAMEDMUTEX,
-               (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL | MONO_W32HANDLE_CAP_OWN));
-}
-
-static const char* mutex_handle_type_to_string (MonoW32HandleType type)
-{
-       switch (type) {
-       case MONO_W32HANDLE_MUTEX: return "mutex";
-       case MONO_W32HANDLE_NAMEDMUTEX: return "named mutex";
-       default:
-               g_assert_not_reached ();
-       }
-}
-
-static gboolean
-mutex_handle_own (gpointer handle, MonoW32HandleType type)
-{
-       struct _WapiHandle_mutex *mutex_handle;
-
-       if (!mono_w32handle_lookup (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);
-
-       mono_thread_info_own_mutex (mono_thread_info_current (), handle);
-
-       mutex_handle->tid = pthread_self ();
-       mutex_handle->recursion++;
-
-       mono_w32handle_set_signal_state (handle, FALSE, FALSE);
-
-       return TRUE;
-}
-
-static gboolean
-mutex_handle_is_owned (gpointer handle, MonoW32HandleType type)
-{
-       struct _WapiHandle_mutex *mutex_handle;
-
-       if (!mono_w32handle_lookup (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 %s handle %p",
-               __func__, mutex_handle_type_to_string (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__, mutex_handle_type_to_string (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, 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 mutex_signal(gpointer handle)
-{
-       ReleaseMutex(handle);
-}
-
-static gboolean mutex_own (gpointer handle)
-{
-       return mutex_handle_own (handle, MONO_W32HANDLE_MUTEX);
-}
-
-static gboolean mutex_is_owned (gpointer handle)
-{
-       
-       return mutex_handle_is_owned (handle, MONO_W32HANDLE_MUTEX);
-}
-
-static void namedmutex_signal (gpointer handle)
-{
-       ReleaseMutex(handle);
-}
-
-/* NB, always called with the shared handle lock held */
-static gboolean namedmutex_own (gpointer handle)
-{
-       return mutex_handle_own (handle, MONO_W32HANDLE_NAMEDMUTEX);
-}
-
-static gboolean namedmutex_is_owned (gpointer handle)
-{
-       return mutex_handle_is_owned (handle, MONO_W32HANDLE_NAMEDMUTEX);
-}
-
-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.
-        */
-       struct _WapiHandle_mutex *mutex_handle;
-
-       if (!mono_w32handle_lookup (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: pre-waiting %s handle %p, owned? %s",
-               __func__, mutex_handle_type_to_string (type), handle, mutex_handle->recursion != 0 ? "true" : "false");
-}
-
-/* The shared state is not locked when prewait methods are called */
-static void mutex_prewait (gpointer handle)
-{
-       mutex_handle_prewait (handle, MONO_W32HANDLE_MUTEX);
-}
-
-/* The shared state is not locked when prewait methods are called */
-static void namedmutex_prewait (gpointer handle)
-{
-       mutex_handle_prewait (handle, MONO_W32HANDLE_NAMEDMUTEX);
-}
-
-static void mutex_details (gpointer data)
-{
-       struct _WapiHandle_mutex *mut = (struct _WapiHandle_mutex *)data;
-       
-#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
-}
-
-static void namedmutex_details (gpointer data)
-{
-       struct _WapiHandle_namedmutex *namedmut = (struct _WapiHandle_namedmutex *)data;
-       
-#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
-}
-
-static const gchar* mutex_typename (void)
-{
-       return "Mutex";
-}
-
-static gsize mutex_typesize (void)
-{
-       return sizeof (struct _WapiHandle_mutex);
-}
-
-static const gchar* namedmutex_typename (void)
-{
-       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)
-{
-       MonoW32HandleType type;
-       struct _WapiHandle_mutex *mutex_handle;
-       int thr_ret;
-
-       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_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: abandon %s handle %p",
-               __func__, mutex_handle_type_to_string (type), handle);
-
-       thr_ret = mono_w32handle_lock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       if (pthread_equal (mutex_handle->tid, tid)) {
-               mutex_handle->recursion = 0;
-               mutex_handle->tid = 0;
-
-               mono_w32handle_set_signal_state (handle, TRUE, FALSE);
-
-               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 = mono_w32handle_unlock_handle (handle);
-       g_assert (thr_ret == 0);
-}
-
-static gpointer mutex_handle_create (struct _WapiHandle_mutex *mutex_handle, MonoW32HandleType type, gboolean owned)
-{
-       gpointer handle;
-       int thr_ret;
-
-       mutex_handle->tid = 0;
-       mutex_handle->recursion = 0;
-
-       handle = mono_w32handle_new (type, mutex_handle);
-       if (handle == INVALID_HANDLE_VALUE) {
-               g_warning ("%s: error creating %s handle",
-                       __func__, mutex_handle_type_to_string (type));
-               SetLastError (ERROR_GEN_FAILURE);
-               return NULL;
-       }
-
-       thr_ret = mono_w32handle_lock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       if (owned)
-               mutex_handle_own (handle, type);
-       else
-               mono_w32handle_set_signal_state (handle, TRUE, FALSE);
-
-       thr_ret = mono_w32handle_unlock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       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 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 (MONO_W32HANDLE_MUTEX));
-       return mutex_handle_create (&mutex_handle, MONO_W32HANDLE_MUTEX, owned);
-}
-
-static gpointer namedmutex_create (gboolean owned, const gunichar2 *name)
-{
-       gpointer handle;
-       gchar *utf8_name;
-       int thr_ret;
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle",
-               __func__, mutex_handle_type_to_string (MONO_W32HANDLE_NAMEDMUTEX));
-
-       /* w32 seems to guarantee that opening named objects can't race each other */
-       thr_ret = _wapi_namespace_lock ();
-       g_assert (thr_ret == 0);
-
-       utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
-
-       handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDMUTEX, 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 mutex wasn't freshly created */
-               SetLastError (ERROR_ALREADY_EXISTS);
-
-               /* this is used as creating a new handle */
-               mono_w32handle_ref (handle);
-       } else {
-               /* A new named mutex */
-               struct _WapiHandle_namedmutex namedmutex_handle;
-
-               strncpy (&namedmutex_handle.sharedns.name [0], utf8_name, MAX_PATH);
-               namedmutex_handle.sharedns.name [MAX_PATH] = '\0';
-
-               handle = mutex_handle_create ((struct _WapiHandle_mutex*) &namedmutex_handle, MONO_W32HANDLE_NAMEDMUTEX, owned);
-       }
-
-       g_free (utf8_name);
-
-       thr_ret = _wapi_namespace_unlock (NULL);
-       g_assert (thr_ret == 0);
-
-       return handle;
-}
-
-/**
- * CreateMutex:
- * @security: Ignored for now.
- * @owned: If %TRUE, the mutex is created with the calling thread
- * already owning the mutex.
- * @name:Pointer to a string specifying the name of this mutex, or
- * %NULL.
- *
- * Creates a new mutex handle.  A mutex is signalled when no thread
- * owns it.  A thread acquires ownership of the mutex by waiting for
- * it with WaitForSingleObject() or WaitForMultipleObjects().  A
- * thread relinquishes ownership with ReleaseMutex().
- *
- * A thread that owns a mutex can specify the same mutex in repeated
- * wait function calls without blocking.  The thread must call
- * ReleaseMutex() an equal number of times to release the mutex.
- *
- * Return value: A new handle, or %NULL on error.
- */
-gpointer CreateMutex(WapiSecurityAttributes *security G_GNUC_UNUSED, gboolean owned, const gunichar2 *name)
-{
-       /* 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);
-
-       return name ? namedmutex_create (owned, name) : mutex_create (owned);
-}
-
-/**
- * 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)
-{
-       MonoW32HandleType type;
-       struct _WapiHandle_mutex *mutex_handle;
-       pthread_t tid;
-       int thr_ret;
-       gboolean ret;
-
-       if (handle == NULL) {
-               SetLastError (ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-
-       switch (type = mono_w32handle_get_type (handle)) {
-       case MONO_W32HANDLE_MUTEX:
-       case MONO_W32HANDLE_NAMEDMUTEX:
-               break;
-       default:
-               SetLastError (ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-
-       if (!mono_w32handle_lookup (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: releasing %s handle %p",
-               __func__, mutex_handle_type_to_string (type), handle);
-
-       thr_ret = mono_w32handle_lock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       tid = pthread_self ();
-
-       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__, mutex_handle_type_to_string (type), handle, mutex_handle->tid, tid);
-       } else {
-               ret = TRUE;
-
-               /* OK, we own this mutex */
-               mutex_handle->recursion--;
-
-               if (mutex_handle->recursion == 0) {
-                       mono_thread_info_disown_mutex (mono_thread_info_current (), handle);
-
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking %s handle %p",
-                               __func__, mutex_handle_type_to_string (type), handle);
-
-                       mutex_handle->tid = 0;
-                       mono_w32handle_set_signal_state (handle, TRUE, FALSE);
-               }
-       }
-
-       thr_ret = mono_w32handle_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)
-{
-       gpointer handle;
-       gchar *utf8_name;
-       int thr_ret;
-
-       /* w32 seems to guarantee that opening named objects can't
-        * race each other
-        */
-       thr_ret = _wapi_namespace_lock ();
-       g_assert (thr_ret == 0);
-
-       utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
-       
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening named mutex [%s]", __func__, utf8_name);
-       
-       handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDMUTEX,
-                                               utf8_name);
-       if (handle == INVALID_HANDLE_VALUE) {
-               /* The name has already been used for a different
-                * object.
-                */
-               SetLastError (ERROR_INVALID_HANDLE);
-               goto cleanup;
-       } else if (!handle) {
-               /* This name doesn't exist */
-               SetLastError (ERROR_FILE_NOT_FOUND);    /* yes, really */
-               goto cleanup;
-       }
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning named mutex handle %p", __func__, handle);
-
-cleanup:
-       g_free (utf8_name);
-
-       _wapi_namespace_unlock (NULL);
-       
-       return handle;
-}
diff --git a/mono/io-layer/mutexes.h b/mono/io-layer/mutexes.h
deleted file mode 100644 (file)
index d1b7a68..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * mutexes.h: Mutex handles
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#ifndef _WAPI_MUTEXES_H_
-#define _WAPI_MUTEXES_H_
-
-#include <glib.h>
-
-#include <pthread.h>
-
-G_BEGIN_DECLS
-
-extern gpointer CreateMutex (WapiSecurityAttributes *security, gboolean owned,
-                            const gunichar2 *name);
-extern gboolean ReleaseMutex (gpointer handle);
-extern gpointer OpenMutex (guint32 access, gboolean inherit,
-                          const gunichar2 *name);
-
-void
-wapi_mutex_abandon (gpointer data, pid_t pid, pthread_t tid);
-
-G_END_DECLS
-
-#endif /* _WAPI_MUTEXES_H_ */
diff --git a/mono/io-layer/semaphore-private.h b/mono/io-layer/semaphore-private.h
deleted file mode 100644 (file)
index 3c27eef..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * semaphore-private.h:  Private definitions for semaphore handles
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#ifndef _WAPI_SEMAPHORE_PRIVATE_H_
-#define _WAPI_SEMAPHORE_PRIVATE_H_
-
-#include <config.h>
-#include <glib.h>
-
-#include "wapi-private.h"
-
-/* emulate sem_t, so that we can prod the internal state more easily */
-struct _WapiHandle_sem
-{
-       guint32 val;
-       gint32 max;
-};
-
-struct _WapiHandle_namedsem
-{
-       struct _WapiHandle_sem s;
-       WapiSharedNamespace sharedns;
-};
-
-void
-_wapi_semaphore_init (void);
-
-#endif /* _WAPI_SEMAPHORE_PRIVATE_H_ */
diff --git a/mono/io-layer/semaphores.c b/mono/io-layer/semaphores.c
deleted file mode 100644 (file)
index c473f4d..0000000
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * semaphores.c:  Semaphore handles
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#include <config.h>
-#include <glib.h>
-#include <pthread.h>
-#ifdef HAVE_SEMAPHORE_H
-#include <semaphore.h>
-#endif
-#include <errno.h>
-#include <string.h>
-#include <sys/time.h>
-
-#include <mono/io-layer/wapi.h>
-#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/semaphore-private.h>
-#include <mono/io-layer/io-trace.h>
-#include <mono/utils/mono-once.h>
-#include <mono/utils/mono-logger-internals.h>
-#include <mono/utils/w32handle.h>
-
-static void sema_signal(gpointer handle);
-static gboolean sema_own (gpointer handle);
-static void sema_details (gpointer data);
-static const gchar* sema_typename (void);
-static gsize sema_typesize (void);
-
-static void namedsema_signal (gpointer handle);
-static gboolean namedsema_own (gpointer handle);
-static void namedsema_details (gpointer data);
-static const gchar* namedsema_typename (void);
-static gsize namedsema_typesize (void);
-
-static MonoW32HandleOps _wapi_sem_ops = {
-       NULL,                   /* close */
-       sema_signal,            /* signal */
-       sema_own,               /* own */
-       NULL,                   /* is_owned */
-       NULL,                   /* special_wait */
-       NULL,                   /* prewait */
-       sema_details,   /* details */
-       sema_typename,  /* typename */
-       sema_typesize,  /* typesize */
-};
-
-static MonoW32HandleOps _wapi_namedsem_ops = {
-       NULL,                   /* close */
-       namedsema_signal,       /* signal */
-       namedsema_own,          /* own */
-       NULL,                   /* is_owned */
-       NULL,                   /* special_wait */
-       NULL,                   /* prewait */
-       namedsema_details,      /* details */
-       namedsema_typename,     /* typename */
-       namedsema_typesize,     /* typesize */
-};
-
-void
-_wapi_semaphore_init (void)
-{
-       mono_w32handle_register_ops (MONO_W32HANDLE_SEM,      &_wapi_sem_ops);
-       mono_w32handle_register_ops (MONO_W32HANDLE_NAMEDSEM, &_wapi_namedsem_ops);
-
-       mono_w32handle_register_capabilities (MONO_W32HANDLE_SEM,
-               (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
-       mono_w32handle_register_capabilities (MONO_W32HANDLE_NAMEDSEM,
-               (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
-}
-
-static const char* sem_handle_type_to_string (MonoW32HandleType type)
-{
-       switch (type) {
-       case MONO_W32HANDLE_SEM: return "sem";
-       case MONO_W32HANDLE_NAMEDSEM: return "named sem";
-       default:
-               g_assert_not_reached ();
-       }
-}
-
-static gboolean sem_handle_own (gpointer handle, MonoW32HandleType type)
-{
-       struct _WapiHandle_sem *sem_handle;
-
-       if (!mono_w32handle_lookup (handle, type, (gpointer *)&sem_handle)) {
-               g_warning ("%s: error looking up %s handle %p",
-                       __func__, sem_handle_type_to_string (type), handle);
-               return FALSE;
-       }
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning %s handle %p",
-               __func__, sem_handle_type_to_string (type), handle);
-
-       sem_handle->val--;
-
-       if (sem_handle->val == 0)
-               mono_w32handle_set_signal_state (handle, FALSE, FALSE);
-
-       return TRUE;
-}
-
-static void sema_signal(gpointer handle)
-{
-       ReleaseSemaphore(handle, 1, NULL);
-}
-
-static gboolean sema_own (gpointer handle)
-{
-       return sem_handle_own (handle, MONO_W32HANDLE_SEM);
-}
-
-static void namedsema_signal (gpointer handle)
-{
-       ReleaseSemaphore (handle, 1, NULL);
-}
-
-/* NB, always called with the shared handle lock held */
-static gboolean namedsema_own (gpointer handle)
-{
-       return sem_handle_own (handle, MONO_W32HANDLE_NAMEDSEM);
-}
-
-static void sema_details (gpointer data)
-{
-       struct _WapiHandle_sem *sem = (struct _WapiHandle_sem *)data;
-       g_print ("val: %5u, max: %5d", sem->val, sem->max);
-}
-
-static void namedsema_details (gpointer data)
-{
-       struct _WapiHandle_namedsem *namedsem = (struct _WapiHandle_namedsem *)data;
-       g_print ("val: %5u, max: %5d, name: \"%s\"", namedsem->s.val, namedsem->s.max, namedsem->sharedns.name);
-}
-
-static const gchar* sema_typename (void)
-{
-       return "Semaphore";
-}
-
-static gsize sema_typesize (void)
-{
-       return sizeof (struct _WapiHandle_sem);
-}
-
-static const gchar* namedsema_typename (void)
-{
-       return "N.Semaphore";
-}
-
-static gsize namedsema_typesize (void)
-{
-       return sizeof (struct _WapiHandle_namedsem);
-}
-
-static gpointer sem_handle_create (struct _WapiHandle_sem *sem_handle, MonoW32HandleType type, gint32 initial, gint32 max)
-{
-       gpointer handle;
-       int thr_ret;
-
-       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__, sem_handle_type_to_string (type));
-               SetLastError (ERROR_GEN_FAILURE);
-               return NULL;
-       }
-
-       thr_ret = mono_w32handle_lock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       if (initial != 0)
-               mono_w32handle_set_signal_state (handle, TRUE, FALSE);
-
-       thr_ret = mono_w32handle_unlock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created %s handle %p",
-               __func__, sem_handle_type_to_string (type), handle);
-
-       return handle;
-}
-
-static gpointer sem_create (gint32 initial, gint32 max)
-{
-       struct _WapiHandle_sem sem_handle;
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle, initial %d max %d",
-               __func__, sem_handle_type_to_string (MONO_W32HANDLE_SEM), initial, max);
-       return sem_handle_create (&sem_handle, MONO_W32HANDLE_SEM, initial, max);
-}
-
-static gpointer namedsem_create (gint32 initial, gint32 max, const gunichar2 *name)
-{
-       gpointer handle;
-       gchar *utf8_name;
-       int thr_ret;
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle, initial %d max %d name \"%s\"",
-               __func__, sem_handle_type_to_string (MONO_W32HANDLE_NAMEDSEM), initial, max, name);
-
-       /* w32 seems to guarantee that opening named objects can't race each other */
-       thr_ret = _wapi_namespace_lock ();
-       g_assert (thr_ret == 0);
-
-       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 = _wapi_search_handle_namespace (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);
-
-               /* this is used as creating a new handle */
-               mono_w32handle_ref (handle);
-       } else {
-               /* A new named semaphore */
-               struct _WapiHandle_namedsem namedsem_handle;
-
-               strncpy (&namedsem_handle.sharedns.name [0], utf8_name, MAX_PATH);
-               namedsem_handle.sharedns.name [MAX_PATH] = '\0';
-
-               handle = sem_handle_create ((struct _WapiHandle_sem*) &namedsem_handle, MONO_W32HANDLE_NAMEDSEM, initial, max);
-       }
-
-       g_free (utf8_name);
-
-       thr_ret = _wapi_namespace_unlock (NULL);
-       g_assert (thr_ret == 0);
-
-       return handle;
-}
-
-
-/**
- * CreateSemaphore:
- * @security: Ignored for now.
- * @initial: The initial count for the semaphore.  The value must be
- * greater than or equal to zero, and less than or equal to @max.
- * @max: The maximum count for this semaphore.  The value must be
- * greater than zero.
- * @name: Pointer to a string specifying the name of this semaphore,
- * or %NULL.  Currently ignored.
- *
- * Creates a new semaphore handle.  A semaphore is signalled when its
- * count is greater than zero, and unsignalled otherwise.  The count
- * is decreased by one whenever a wait function releases a thread that
- * was waiting for the semaphore.  The count is increased by calling
- * ReleaseSemaphore().
- *
- * Return value: a new handle, or NULL
- */
-gpointer CreateSemaphore(WapiSecurityAttributes *security G_GNUC_UNUSED, gint32 initial, gint32 max, const gunichar2 *name)
-{
-       if (max <= 0) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: max <= 0", __func__);
-
-               SetLastError (ERROR_INVALID_PARAMETER);
-               return(NULL);
-       }
-       
-       if (initial > max || initial < 0) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: initial>max or < 0", __func__);
-
-               SetLastError (ERROR_INVALID_PARAMETER);
-               return(NULL);
-       }
-
-       /* Need to blow away any old errors here, because code tests
-        * for ERROR_ALREADY_EXISTS on success (!) to see if a
-        * semaphore was freshly created
-        */
-       SetLastError (ERROR_SUCCESS);
-
-       return name ? namedsem_create (initial, max, name) : sem_create (initial, max);
-}
-
-/**
- * ReleaseSemaphore:
- * @handle: The semaphore handle to release.
- * @count: The amount by which the semaphore's count should be
- * increased.
- * @prevcount: Pointer to a location to store the previous count of
- * the semaphore, or %NULL.
- *
- * Increases the count of semaphore @handle by @count.
- *
- * Return value: %TRUE on success, %FALSE otherwise.
- */
-gboolean ReleaseSemaphore(gpointer handle, gint32 count, gint32 *prevcount)
-{
-       MonoW32HandleType type;
-       struct _WapiHandle_sem *sem_handle;
-       int thr_ret;
-       gboolean 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__, sem_handle_type_to_string (type), handle);
-
-       thr_ret = mono_w32handle_lock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       /* 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 + count > (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__, sem_handle_type_to_string (type), handle, sem_handle->val, count, sem_handle->max, count);
-
-               ret = FALSE;
-       } else {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s handle %p val %d count %d max %d",
-                       __func__, sem_handle_type_to_string (type), handle, sem_handle->val, count, sem_handle->max, count);
-
-               sem_handle->val += count;
-               mono_w32handle_set_signal_state (handle, TRUE, TRUE);
-
-               ret = TRUE;
-       }
-
-       thr_ret = mono_w32handle_unlock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       return ret;
-}
-
-gpointer OpenSemaphore (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED,
-                       const gunichar2 *name)
-{
-       gpointer handle;
-       gchar *utf8_name;
-       int thr_ret;
-
-       /* w32 seems to guarantee that opening named objects can't
-        * race each other
-        */
-       thr_ret = _wapi_namespace_lock ();
-       g_assert (thr_ret == 0);
-       
-       utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
-       
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening named sem [%s]", __func__, utf8_name);
-
-       handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDSEM,
-                                               utf8_name);
-       if (handle == INVALID_HANDLE_VALUE) {
-               /* The name has already been used for a different
-                * object.
-                */
-               SetLastError (ERROR_INVALID_HANDLE);
-               goto cleanup;
-       } else if (!handle) {
-               /* This name doesn't exist */
-               SetLastError (ERROR_FILE_NOT_FOUND);    /* yes, really */
-               goto cleanup;
-       }
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning named sem handle %p", __func__, handle);
-
-cleanup:
-       g_free (utf8_name);
-       
-       _wapi_namespace_unlock (NULL);
-       
-       return handle;
-}
diff --git a/mono/io-layer/semaphores.h b/mono/io-layer/semaphores.h
deleted file mode 100644 (file)
index 1cdaee0..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * semaphores.h:  Semaphore handles
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#ifndef _WAPI_SEMAPHORES_H_
-#define _WAPI_SEMAPHORES_H_
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-extern gpointer CreateSemaphore(WapiSecurityAttributes *security,
-                               gint32 initial, gint32 max,
-                               const gunichar2 *name);
-extern gboolean ReleaseSemaphore(gpointer handle, gint32 count,
-                                gint32 *prevcount);
-extern gpointer OpenSemaphore (guint32 access, gboolean inherit,
-                              const gunichar2 *name);
-
-G_END_DECLS
-#endif /* _WAPI_SEMAPHORES_H_ */
diff --git a/mono/io-layer/shared.c b/mono/io-layer/shared.c
deleted file mode 100644 (file)
index 8fb0e27..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * shared.c:  Shared memory handling, and daemon launching
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002-2006 Novell, Inc.
- */
-
-#include <config.h>
-#include <glib.h>
-
-#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/shared.h>
-#include <mono/utils/mono-os-mutex.h>
-
-#define DEBUGLOG(...)
-//#define DEBUGLOG(...) g_message(__VA_ARGS__);
-
-static mono_mutex_t noshm_sems[_WAPI_SHARED_SEM_COUNT];
-
-void
-_wapi_shm_semaphores_init (void)
-{
-       int i;
-       for (i = 0; i < _WAPI_SHARED_SEM_COUNT; i++) 
-               mono_os_mutex_init (&noshm_sems [i]);
-}
-
-int
-_wapi_shm_sem_lock (int sem)
-{
-       DEBUGLOG ("%s: locking nosem %d", __func__, sem);
-       mono_os_mutex_lock (&noshm_sems[sem]);
-       return 0;
-}
-
-int
-_wapi_shm_sem_trylock (int sem)
-{
-       DEBUGLOG ("%s: trying to lock nosem %d", __func__, sem);
-       return mono_os_mutex_trylock (&noshm_sems[sem]);
-}
-
-int
-_wapi_shm_sem_unlock (int sem)
-{
-       DEBUGLOG ("%s: unlocking nosem %d", __func__, sem);
-       mono_os_mutex_unlock (&noshm_sems[sem]);
-       return 0;
-}
diff --git a/mono/io-layer/shared.h b/mono/io-layer/shared.h
deleted file mode 100644 (file)
index 204f506..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * shared.h:  Shared memory handle, and daemon launching
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002-2006 Novell, Inc.
- */
-
-#ifndef _WAPI_SHARED_H_
-#define _WAPI_SHARED_H_
-
-extern void _wapi_shm_semaphores_init (void);
-extern int _wapi_shm_sem_lock (int sem);
-extern int _wapi_shm_sem_trylock (int sem);
-extern int _wapi_shm_sem_unlock (int sem);
-
-#endif /* _WAPI_SHARED_H_ */
index ee961002d9eec7152e3741e77299836cab989d14..8b82b609d1976be0cf356e0d13904f970aa8b585 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <mono/io-layer/wapi.h>
 #include <mono/io-layer/io.h>
-#include <mono/io-layer/shared.h>
 
 #include <mono/utils/mono-os-mutex.h>
 
 
 extern gboolean _wapi_has_shut_down;
 
-typedef struct 
-{
-       gchar name[MAX_PATH + 1];
-} WapiSharedNamespace;
-
-#include <mono/io-layer/event-private.h>
 #include <mono/io-layer/io-private.h>
-#include <mono/io-layer/mutex-private.h>
-#include <mono/io-layer/semaphore-private.h>
 #include <mono/io-layer/socket-private.h>
 #include <mono/io-layer/process-private.h>
 #include <mono/utils/w32handle.h>
@@ -46,13 +37,6 @@ struct _WapiHandle_shared_ref
        guint32 offset;
 };
 
-#define _WAPI_SHARED_SEM_NAMESPACE 0
-/*#define _WAPI_SHARED_SEM_COLLECTION 1*/
-#define _WAPI_SHARED_SEM_FILESHARE 2
-#define _WAPI_SHARED_SEM_PROCESS_COUNT_LOCK 6
-#define _WAPI_SHARED_SEM_PROCESS_COUNT 7
-#define _WAPI_SHARED_SEM_COUNT 8       /* Leave some future expansion space */
-
 struct _WapiFileShare
 {
 #ifdef WAPI_FILE_SHARE_PLATFORM_EXTRA_DATA
@@ -69,18 +53,4 @@ struct _WapiFileShare
 
 typedef struct _WapiFileShare _WapiFileShare;
 
-gpointer
-_wapi_search_handle_namespace (MonoW32HandleType type, gchar *utf8_name);
-
-static inline int _wapi_namespace_lock (void)
-{
-       return(_wapi_shm_sem_lock (_WAPI_SHARED_SEM_NAMESPACE));
-}
-
-/* This signature makes it easier to use in pthread cleanup handlers */
-static inline int _wapi_namespace_unlock (gpointer data G_GNUC_UNUSED)
-{
-       return(_wapi_shm_sem_unlock (_WAPI_SHARED_SEM_NAMESPACE));
-}
-
 #endif /* _WAPI_PRIVATE_H_ */
index 8f8b4ff549d87ad0e142368bf773277c4e5351d7..935d257722557872189afa90b439e60a2d57ff99 100644 (file)
 #define SetLastError wapi_SetLastError
 #define TransmitFile wapi_TransmitFile
 #define GetThreadContext wapi_GetThreadContext
-#define CreateEvent wapi_CreateEvent 
-#define PulseEvent wapi_PulseEvent 
-#define ResetEvent wapi_ResetEvent 
-#define SetEvent wapi_SetEvent 
-#define OpenEvent wapi_OpenEvent 
 #define CloseHandle wapi_CloseHandle 
 #define DuplicateHandle wapi_DuplicateHandle 
 #define CreateFile wapi_CreateFile
@@ -57,9 +52,6 @@
 #define UnlockFile wapi_UnlockFile 
 #define GetVolumeInformation wapi_GetVolumeInformation 
 #define FormatMessage wapi_FormatMessage 
-#define CreateMutex wapi_CreateMutex 
-#define ReleaseMutex wapi_ReleaseMutex 
-#define OpenMutex wapi_OpenMutex 
 #define ShellExecuteEx wapi_ShellExecuteEx 
 #define CreateProcess wapi_CreateProcess 
 #define CreateProcessWithLogonW wapi_CreateProcessWithLogonW 
@@ -80,9 +72,6 @@
 #define SetPriorityClass wapi_SetPriorityClass 
 #define ImpersonateLoggedOnUser wapi_ImpersonateLoggedOnUser 
 #define RevertToSelf wapi_RevertToSelf 
-#define CreateSemaphore wapi_CreateSemaphore
-#define ReleaseSemaphore wapi_ReleaseSemaphore
-#define OpenSemaphore wapi_OpenSemaphore 
 #define WSASetLastError wapi_WSASetLastError
 #define WSAGetLastError wapi_WSAGetLastError
 #define WSAIoctl wapi_WSAIoctl 
index a9f93692400dbc03c96557e20ef08fc86a7aa793..f1674179d9a194f0d2dcb4d992acbf5bb6926d3c 100644 (file)
@@ -1,13 +1,9 @@
 
 #include "wapi.h"
 
-#include "event-private.h"
 #include "io-trace.h"
 #include "io.h"
-#include "mutex-private.h"
 #include "process-private.h"
-#include "semaphore-private.h"
-#include "shared.h"
 #include "socket-private.h"
 
 #include "mono/utils/mono-lazy-init.h"
@@ -18,12 +14,8 @@ gboolean _wapi_has_shut_down = FALSE;
 void
 wapi_init (void)
 {
-       _wapi_shm_semaphores_init ();
        _wapi_io_init ();
        _wapi_processes_init ();
-       _wapi_semaphore_init ();
-       _wapi_mutex_init ();
-       _wapi_event_init ();
        _wapi_socket_init ();
 }
 
@@ -57,82 +49,6 @@ wapi_getpid (void)
        return _wapi_pid;
 }
 
-static gboolean
-_WAPI_SHARED_NAMESPACE (MonoW32HandleType type)
-{
-       switch (type) {
-       case MONO_W32HANDLE_NAMEDMUTEX:
-       case MONO_W32HANDLE_NAMEDSEM:
-       case MONO_W32HANDLE_NAMEDEVENT:
-               return TRUE;
-       default:
-               return FALSE;
-       }
-}
-
-typedef struct {
-       gpointer ret;
-       MonoW32HandleType type;
-       gchar *utf8_name;
-} _WapiSearchHandleNamespaceData;
-
-static gboolean mono_w32handle_search_namespace_callback (gpointer handle, gpointer data, gpointer user_data)
-{
-       _WapiSearchHandleNamespaceData *search_data;
-       MonoW32HandleType type;
-       WapiSharedNamespace *sharedns;
-
-       type = mono_w32handle_get_type (handle);
-       if (!_WAPI_SHARED_NAMESPACE (type))
-               return FALSE;
-
-       search_data = (_WapiSearchHandleNamespaceData*) user_data;
-
-       switch (type) {
-       case MONO_W32HANDLE_NAMEDMUTEX: sharedns = &((struct _WapiHandle_namedmutex*) data)->sharedns; break;
-       case MONO_W32HANDLE_NAMEDSEM:   sharedns = &((struct _WapiHandle_namedsem*)   data)->sharedns; break;
-       case MONO_W32HANDLE_NAMEDEVENT: sharedns = &((struct _WapiHandle_namedevent*) data)->sharedns; break;
-       default:
-               g_assert_not_reached ();
-       }
-
-       if (strcmp (sharedns->name, search_data->utf8_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_ops_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);
-                       search_data->ret = handle;
-               }
-
-               return TRUE;
-       }
-
-       return FALSE;
-}
-
-/* Returns the offset of the metadata array, or INVALID_HANDLE_VALUE on error, or NULL for
- * not found
- */
-gpointer _wapi_search_handle_namespace (MonoW32HandleType type, gchar *utf8_name)
-{
-       _WapiSearchHandleNamespaceData search_data;
-
-       g_assert(_WAPI_SHARED_NAMESPACE(type));
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Lookup for handle named [%s] type %s",
-               __func__, utf8_name, mono_w32handle_ops_typename (type));
-
-       search_data.ret = NULL;
-       search_data.type = type;
-       search_data.utf8_name = utf8_name;
-       mono_w32handle_foreach (mono_w32handle_search_namespace_callback, &search_data);
-       return search_data.ret;
-}
-
 /* Lots more to implement here, but this is all we need at the moment */
 gboolean
 DuplicateHandle (gpointer srcprocess, gpointer src, gpointer targetprocess, gpointer *target,
index 4e0a688063984ad671543a10f51a4bc2d27290c7..c56622ea91c003c548288148cf8c49f9998c22bd 100644 (file)
 #include <mono/io-layer/access.h>
 #include <mono/io-layer/context.h>
 #include <mono/io-layer/error.h>
-#include <mono/io-layer/events.h>
 #include <mono/io-layer/messages.h>
-#include <mono/io-layer/mutexes.h>
 #include <mono/io-layer/processes.h>
 #include <mono/io-layer/security.h>
-#include <mono/io-layer/semaphores.h>
 #include <mono/io-layer/sockets.h>
 #include <mono/io-layer/status.h>
 #include <mono/io-layer/timefuncs.h>
index f49dde50193159d9d0525370300142fe2551b50c..f19773b6a2ffa8e1c1bafb1ea9a866b3b7e049c2 100644 (file)
@@ -1,6 +1,9 @@
 if HOST_WIN32
 win32_sources = \
-       console-win32.c
+       console-win32.c \
+       w32mutex-win32.c \
+       w32semaphore-win32.c \
+       w32event-win32.c
 
 platform_sources = $(win32_sources)
 
@@ -23,7 +26,10 @@ else
 assembliesdir = $(exec_prefix)/lib
 confdir = $(sysconfdir)
 unix_sources = \
-       console-unix.c
+       console-unix.c \
+       w32mutex-unix.c \
+       w32semaphore-unix.c \
+       w32event-unix.c
 
 platform_sources = $(unix_sources)
 endif
@@ -217,8 +223,12 @@ common_sources = \
        seq-points-data.h       \
        seq-points-data.c       \
        handle.c        \
-       handle.h
-
+       handle.h        \
+       w32mutex.h      \
+       w32semaphore.h  \
+       w32event.h      \
+       w32handle-namespace.h   \
+       w32handle-namespace.c
 
 # These source files have compile time dependencies on GC code
 gc_dependent_sources = \
index 5e698eafc7fe0693f84e62184c95de0ea5dcd095..422ce454283cc247c08fd2c690f7bbae3406225d 100644 (file)
@@ -40,6 +40,9 @@
 #include <mono/metadata/mono-config.h>
 #include <mono/metadata/threads-types.h>
 #include <mono/metadata/runtime.h>
+#include <mono/metadata/w32mutex.h>
+#include <mono/metadata/w32semaphore.h>
+#include <mono/metadata/w32event.h>
 #include <metadata/threads.h>
 #include <metadata/profiler-private.h>
 #include <mono/metadata/coree.h>
@@ -526,9 +529,14 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
 
 #ifndef HOST_WIN32
        mono_w32handle_init ();
+       mono_w32handle_namespace_init ();
        wapi_init ();
 #endif
 
+       mono_w32mutex_init ();
+       mono_w32semaphore_init ();
+       mono_w32event_init ();
+
 #ifndef DISABLE_PERFCOUNTERS
        mono_perfcounters_init ();
 #endif
index 95374177657f2c3ec76172736bd339e1cdef396b..6403f1975e91d48c89fe2a8b4a70a8d04940e351 100644 (file)
@@ -83,6 +83,9 @@
 #include <mono/metadata/file-mmap.h>
 #include <mono/metadata/seq-points-data.h>
 #include <mono/metadata/handle.h>
+#include <mono/metadata/w32mutex.h>
+#include <mono/metadata/w32semaphore.h>
+#include <mono/metadata/w32event.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/utils/monobitset.h>
 #include <mono/utils/mono-time.h>
index 8c178a0db39acf932aca513ee7276f5e93c9944e..8b7418e9659e139dd21ba614910f4b2a9aea97e6 100644 (file)
@@ -26,6 +26,7 @@
 #include <mono/metadata/debug-helpers.h>
 #include <mono/metadata/tabledefs.h>
 #include <mono/metadata/marshal.h>
+#include <mono/metadata/w32event.h>
 #include <mono/utils/mono-threads.h>
 #include <mono/metadata/profiler-private.h>
 #include <mono/utils/mono-time.h>
@@ -1246,7 +1247,7 @@ ves_icall_System_Threading_Monitor_Monitor_pulse (MonoObject *obj)
        if (mon->wait_list != NULL) {
                LOCK_DEBUG (g_message ("%s: (%d) signalling and dequeuing handle %p", __func__, mono_thread_info_get_small_id (), mon->wait_list->data));
        
-               SetEvent (mon->wait_list->data);
+               mono_w32event_set (mon->wait_list->data);
                mon->wait_list = g_slist_remove (mon->wait_list, mon->wait_list->data);
        }
 }
@@ -1277,7 +1278,7 @@ ves_icall_System_Threading_Monitor_Monitor_pulse_all (MonoObject *obj)
        while (mon->wait_list != NULL) {
                LOCK_DEBUG (g_message ("%s: (%d) signalling and dequeuing handle %p", __func__, mono_thread_info_get_small_id (), mon->wait_list->data));
        
-               SetEvent (mon->wait_list->data);
+               mono_w32event_set (mon->wait_list->data);
                mon->wait_list = g_slist_remove (mon->wait_list, mon->wait_list->data);
        }
 }
@@ -1312,7 +1313,7 @@ ves_icall_System_Threading_Monitor_Monitor_wait (MonoObject *obj, guint32 ms)
        if (mono_thread_current_check_pending_interrupt ())
                return FALSE;
        
-       event = CreateEvent (NULL, FALSE, FALSE, NULL);
+       event = mono_w32event_create (FALSE, FALSE);
        if (event == NULL) {
                mono_set_pending_exception (mono_get_exception_synchronization_lock ("Failed to set up wait event"));
                return FALSE;
index 917bfd954dba27041bf05c7061747d898e0c3f09..632cc4b66246c3f8c9a170d968cb6d35c1967d51 100644 (file)
@@ -41,6 +41,7 @@
 #include <mono/metadata/gc-internals.h>
 #include <mono/metadata/verify-internals.h>
 #include <mono/metadata/reflection-internals.h>
+#include <mono/metadata/w32event.h>
 #include <mono/utils/strenc.h>
 #include <mono/utils/mono-counters.h>
 #include <mono/utils/mono-error-internals.h>
@@ -7568,7 +7569,7 @@ ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult
                mono_monitor_exit ((MonoObject*) ares);
 
                if (wait_event != NULL)
-                       SetEvent (wait_event);
+                       mono_w32event_set (wait_event);
 
                mono_error_init (&error); //the else branch would leave it in an undefined state
                if (ac->cb_method)
index b214e61e8d6868dba6896604446d6e7f6f55d6b5..462fd69a77f172521b3ff983aae71160b2099aa4 100644 (file)
@@ -33,6 +33,7 @@
 #include <mono/metadata/object-internals.h>
 #include <mono/metadata/threadpool-ms.h>
 #include <mono/metadata/threadpool-ms-io.h>
+#include <mono/metadata/w32event.h>
 #include <mono/utils/atomic.h>
 #include <mono/utils/mono-compiler.h>
 #include <mono/utils/mono-complex.h>
@@ -1426,7 +1427,7 @@ mono_threadpool_ms_end_invoke (MonoAsyncResult *ares, MonoArray **out_args, Mono
                if (ares->handle) {
                        wait_event = mono_wait_handle_get_handle ((MonoWaitHandle*) ares->handle);
                } else {
-                       wait_event = CreateEvent (NULL, TRUE, FALSE, NULL);
+                       wait_event = mono_w32event_create (TRUE, FALSE);
                        g_assert(wait_event);
                        MonoWaitHandle *wait_handle = mono_wait_handle_new (mono_object_domain (ares), wait_event, error);
                        if (!is_ok (error)) {
index b7cca547aaec91e42fb74a4b499c028692747509..ad472a0b9c06030dcc1e3cba4a235bc9c6287517 100644 (file)
@@ -83,17 +83,6 @@ MonoObject* ves_icall_System_Threading_Thread_GetCachedCurrentCulture (MonoInter
 void ves_icall_System_Threading_Thread_SetCachedCurrentCulture (MonoThread *this_obj, MonoObject *culture);
 MonoObject* ves_icall_System_Threading_Thread_GetCachedCurrentUICulture (MonoInternalThread *this_obj);
 void ves_icall_System_Threading_Thread_SetCachedCurrentUICulture (MonoThread *this_obj, MonoObject *culture);
-HANDLE ves_icall_System_Threading_Mutex_CreateMutex_internal(MonoBoolean owned, MonoString *name, MonoBoolean *created);
-MonoBoolean ves_icall_System_Threading_Mutex_ReleaseMutex_internal (HANDLE handle );
-HANDLE ves_icall_System_Threading_Mutex_OpenMutex_internal (MonoString *name, gint32 rights, gint32 *error);
-HANDLE ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 initialCount, gint32 maximumCount, MonoString *name, gint32 *error);
-MonoBoolean ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (HANDLE handle, gint32 releaseCount, gint32 *prevcount);
-HANDLE ves_icall_System_Threading_Semaphore_OpenSemaphore_internal (MonoString *name, gint32 rights, gint32 *error);
-HANDLE ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoString *name, gint32 *error);
-gboolean ves_icall_System_Threading_Events_SetEvent_internal (HANDLE handle);
-gboolean ves_icall_System_Threading_Events_ResetEvent_internal (HANDLE handle);
-void ves_icall_System_Threading_Events_CloseEvent_internal (HANDLE handle);
-HANDLE ves_icall_System_Threading_Events_OpenEvent_internal (MonoString *name, gint32 rights, gint32 *error);
 
 gint32 ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_handles, gint32 ms);
 gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_handles, gint32 ms);
index 251868669b7f846a25bb9d65307e7089d20e2e2c..ab3a11ea5f15e329d54147c82839ff1f3909a639 100644 (file)
@@ -45,6 +45,7 @@
 #include <mono/utils/mono-threads-coop.h>
 #include <mono/utils/mono-error-internals.h>
 #include <mono/utils/w32handle.h>
+#include <mono/metadata/w32event.h>
 
 #include <mono/metadata/gc-internals.h>
 #include <mono/metadata/reflection-internals.h>
@@ -1822,123 +1823,6 @@ ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal (HANDLE toSignal, H
        return map_native_wait_result_to_managed (ret);
 }
 
-HANDLE ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoString *name, MonoBoolean *created)
-{ 
-       HANDLE mutex;
-       
-       *created = TRUE;
-       
-       if (name == NULL) {
-               mutex = CreateMutex (NULL, owned, NULL);
-       } else {
-               mutex = CreateMutex (NULL, owned, mono_string_chars (name));
-               
-               if (GetLastError () == ERROR_ALREADY_EXISTS) {
-                       *created = FALSE;
-               }
-       }
-
-       return(mutex);
-}                                                                   
-
-MonoBoolean ves_icall_System_Threading_Mutex_ReleaseMutex_internal (HANDLE handle ) { 
-       return(ReleaseMutex (handle));
-}
-
-HANDLE ves_icall_System_Threading_Mutex_OpenMutex_internal (MonoString *name,
-                                                           gint32 rights,
-                                                           gint32 *error)
-{
-       HANDLE ret;
-       
-       *error = ERROR_SUCCESS;
-       
-       ret = OpenMutex (rights, FALSE, mono_string_chars (name));
-       if (ret == NULL) {
-               *error = GetLastError ();
-       }
-       
-       return(ret);
-}
-
-
-HANDLE ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 initialCount, gint32 maximumCount, MonoString *name, gint32 *error)
-{ 
-       HANDLE sem;
-       
-       if (name == NULL) {
-               sem = CreateSemaphore (NULL, initialCount, maximumCount, NULL);
-       } else {
-               sem = CreateSemaphore (NULL, initialCount, maximumCount,
-                                      mono_string_chars (name));
-       }
-
-       *error = GetLastError ();
-
-       return(sem);
-}                                                                   
-
-MonoBoolean ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (HANDLE handle, gint32 releaseCount, gint32 *prevcount)
-{ 
-       return ReleaseSemaphore (handle, releaseCount, prevcount);
-}
-
-HANDLE ves_icall_System_Threading_Semaphore_OpenSemaphore_internal (MonoString *name, gint32 rights, gint32 *error)
-{
-       HANDLE sem;
-
-       sem = OpenSemaphore (rights, FALSE, mono_string_chars (name));
-
-       *error = GetLastError ();
-
-       return(sem);
-}
-
-HANDLE ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoString *name, gint32 *error)
-{
-       HANDLE event;
-
-       if (name == NULL) {
-               event = CreateEvent (NULL, manual, initial, NULL);
-       } else {
-               event = CreateEvent (NULL, manual, initial,
-                                    mono_string_chars (name));
-       }
-
-       *error = GetLastError ();
-
-       return(event);
-}
-
-gboolean ves_icall_System_Threading_Events_SetEvent_internal (HANDLE handle) {
-       return (SetEvent(handle));
-}
-
-gboolean ves_icall_System_Threading_Events_ResetEvent_internal (HANDLE handle) {
-       return (ResetEvent(handle));
-}
-
-void
-ves_icall_System_Threading_Events_CloseEvent_internal (HANDLE handle) {
-       CloseHandle (handle);
-}
-
-HANDLE ves_icall_System_Threading_Events_OpenEvent_internal (MonoString *name,
-                                                            gint32 rights,
-                                                            gint32 *error)
-{
-       HANDLE ret;
-       
-       ret = OpenEvent (rights, FALSE, mono_string_chars (name));
-       if (ret == NULL) {
-               *error = GetLastError ();
-       } else {
-               *error = ERROR_SUCCESS;
-       }
-
-       return(ret);
-}
-
 gint32 ves_icall_System_Threading_Interlocked_Increment_Int (gint32 *location)
 {
        return InterlockedIncrement (location);
@@ -2183,7 +2067,7 @@ ves_icall_System_Threading_Thread_ClrState (MonoInternalThread* this_obj, guint3
                 * be notified, since it has to rebuild the list of threads to
                 * wait for.
                 */
-               SetEvent (background_change_event);
+               mono_w32event_set (background_change_event);
        }
 }
 
@@ -2197,7 +2081,7 @@ ves_icall_System_Threading_Thread_SetState (MonoInternalThread* this_obj, guint3
                 * be notified, since it has to rebuild the list of threads to
                 * wait for.
                 */
-               SetEvent (background_change_event);
+               mono_w32event_set (background_change_event);
        }
 }
 
@@ -2948,7 +2832,7 @@ void mono_thread_init (MonoThreadStartCB start_cb,
        mono_os_mutex_init_recursive(&interlocked_mutex);
        mono_os_mutex_init_recursive(&joinable_threads_mutex);
        
-       background_change_event = CreateEvent (NULL, TRUE, FALSE, NULL);
+       background_change_event = mono_w32event_create (TRUE, FALSE);
        g_assert(background_change_event != NULL);
        
        mono_init_static_data_info (&thread_static_info);
@@ -3263,7 +3147,7 @@ mono_threads_set_shutting_down (void)
                 * interrupt the main thread if it is waiting for all
                 * the other threads.
                 */
-               SetEvent (background_change_event);
+               mono_w32event_set (background_change_event);
                
                mono_threads_unlock ();
        }
@@ -3296,7 +3180,7 @@ void mono_thread_manage (void)
                THREAD_DEBUG (g_message ("%s: There are %d threads to join", __func__, mono_g_hash_table_size (threads));
                        mono_g_hash_table_foreach (threads, print_tids, NULL));
        
-               ResetEvent (background_change_event);
+               mono_w32event_reset (background_change_event);
                wait->num=0;
                /*We must zero all InternalThread pointers to avoid making the GC unhappy.*/
                memset (wait->threads, 0, MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS * SIZEOF_VOID_P);
diff --git a/mono/metadata/w32event-unix.c b/mono/metadata/w32event-unix.c
new file mode 100644 (file)
index 0000000..de99585
--- /dev/null
@@ -0,0 +1,411 @@
+/*
+ * w32event-unix.c: Runtime support for managed Event on Unix
+ *
+ * Author:
+ *     Ludovic Henry (luhenry@microsoft.com)
+ *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include "w32event.h"
+
+#include "w32handle-namespace.h"
+#include "mono/io-layer/io-layer.h"
+#include "mono/utils/mono-logger-internals.h"
+#include "mono/utils/w32handle.h"
+
+typedef struct {
+       gboolean manual;
+       guint32 set_count;
+} MonoW32HandleEvent;
+
+struct MonoW32HandleNamedEvent {
+       MonoW32HandleEvent e;
+       MonoW32HandleNamespace sharedns;
+};
+
+static gboolean event_handle_own (gpointer handle, MonoW32HandleType type)
+{
+       MonoW32HandleEvent *event_handle;
+       gboolean ok;
+
+       ok = mono_w32handle_lookup (handle, type, (gpointer *)&event_handle);
+       if (!ok) {
+               g_warning ("%s: error looking up %s handle %p",
+                       __func__, mono_w32handle_ops_typename (type), handle);
+               return FALSE;
+       }
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning %s handle %p",
+               __func__, mono_w32handle_ops_typename (type), handle);
+
+       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, FALSE, FALSE);
+       }
+
+       return TRUE;
+}
+
+static void event_signal(gpointer handle)
+{
+       ves_icall_System_Threading_Events_SetEvent_internal (handle);
+}
+
+static gboolean event_own (gpointer handle)
+{
+       return event_handle_own (handle, MONO_W32HANDLE_EVENT);
+}
+
+static void namedevent_signal (gpointer handle)
+{
+       ves_icall_System_Threading_Events_SetEvent_internal (handle);
+}
+
+/* NB, always called with the shared handle lock held */
+static gboolean namedevent_own (gpointer handle)
+{
+       return event_handle_own (handle, MONO_W32HANDLE_NAMEDEVENT);
+}
+
+static void event_details (gpointer data)
+{
+       MonoW32HandleEvent *event = (MonoW32HandleEvent *)data;
+       g_print ("manual: %s, set_count: %d",
+               event->manual ? "TRUE" : "FALSE", event->set_count);
+}
+
+static void namedevent_details (gpointer data)
+{
+       MonoW32HandleNamedEvent *namedevent = (MonoW32HandleNamedEvent *)data;
+       g_print ("manual: %s, set_count: %d, name: \"%s\"",
+               namedevent->e.manual ? "TRUE" : "FALSE", namedevent->e.set_count, namedevent->sharedns.name);
+}
+
+static const gchar* event_typename (void)
+{
+       return "Event";
+}
+
+static gsize event_typesize (void)
+{
+       return sizeof (MonoW32HandleEvent);
+}
+
+static const gchar* namedevent_typename (void)
+{
+       return "N.Event";
+}
+
+static gsize namedevent_typesize (void)
+{
+       return sizeof (MonoW32HandleNamedEvent);
+}
+
+void
+mono_w32event_init (void)
+{
+       static MonoW32HandleOps event_ops = {
+               NULL,                   /* close */
+               event_signal,           /* signal */
+               event_own,              /* own */
+               NULL,                   /* is_owned */
+               NULL,                   /* special_wait */
+               NULL,                   /* prewait */
+               event_details,  /* details */
+               event_typename, /* typename */
+               event_typesize, /* typesize */
+       };
+
+       static MonoW32HandleOps namedevent_ops = {
+               NULL,                   /* close */
+               namedevent_signal,      /* signal */
+               namedevent_own,         /* own */
+               NULL,                   /* is_owned */
+               NULL,                   /* special_wait */
+               NULL,                   /* prewait */
+               namedevent_details,     /* details */
+               namedevent_typename, /* typename */
+               namedevent_typesize, /* typesize */
+       };
+
+       mono_w32handle_register_ops (MONO_W32HANDLE_EVENT,      &event_ops);
+       mono_w32handle_register_ops (MONO_W32HANDLE_NAMEDEVENT, &namedevent_ops);
+
+       mono_w32handle_register_capabilities (MONO_W32HANDLE_EVENT,
+               (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
+       mono_w32handle_register_capabilities (MONO_W32HANDLE_NAMEDEVENT,
+               (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
+}
+
+gpointer
+mono_w32event_create (gboolean manual, gboolean initial)
+{
+       gpointer handle;
+       gint32 error;
+
+       handle = ves_icall_System_Threading_Events_CreateEvent_internal (manual, initial, NULL, &error);
+       if (error != ERROR_SUCCESS)
+               g_assert (!handle);
+
+       return handle;
+}
+
+void
+mono_w32event_set (gpointer handle)
+{
+       ves_icall_System_Threading_Events_SetEvent_internal (handle);
+}
+
+void
+mono_w32event_reset (gpointer handle)
+{
+       ves_icall_System_Threading_Events_ResetEvent_internal (handle);
+}
+
+static gpointer event_handle_create (MonoW32HandleEvent *event_handle, MonoW32HandleType type, gboolean manual, gboolean initial)
+{
+       gpointer handle;
+       int thr_ret;
+
+       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_ops_typename (type));
+               SetLastError (ERROR_GEN_FAILURE);
+               return NULL;
+       }
+
+       thr_ret = mono_w32handle_lock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       if (initial)
+               mono_w32handle_set_signal_state (handle, TRUE, FALSE);
+
+       thr_ret = mono_w32handle_unlock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created %s handle %p",
+               __func__, mono_w32handle_ops_typename (type), handle);
+
+       return handle;
+}
+
+static gpointer event_create (gboolean manual, gboolean initial)
+{
+       MonoW32HandleEvent event_handle;
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle",
+               __func__, mono_w32handle_ops_typename (MONO_W32HANDLE_EVENT));
+       return event_handle_create (&event_handle, MONO_W32HANDLE_EVENT, manual, initial);
+}
+
+static gpointer namedevent_create (gboolean manual, gboolean initial, const gunichar2 *name G_GNUC_UNUSED)
+{
+       gpointer handle;
+       gchar *utf8_name;
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle",
+               __func__, mono_w32handle_ops_typename (MONO_W32HANDLE_NAMEDEVENT));
+
+       /* 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);
+
+       handle = mono_w32handle_namespace_search_handle (MONO_W32HANDLE_NAMEDEVENT, 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 event wasn't freshly created */
+               SetLastError (ERROR_ALREADY_EXISTS);
+
+               /* this is used as creating a new handle */
+               mono_w32handle_ref (handle);
+       } else {
+               /* A new named event */
+               MonoW32HandleNamedEvent namedevent_handle;
+
+               strncpy (&namedevent_handle.sharedns.name [0], utf8_name, MAX_PATH);
+               namedevent_handle.sharedns.name [MAX_PATH] = '\0';
+
+               handle = event_handle_create ((MonoW32HandleEvent*) &namedevent_handle, MONO_W32HANDLE_NAMEDEVENT, manual, initial);
+       }
+
+       g_free (utf8_name);
+
+       mono_w32handle_namespace_unlock ();
+
+       return handle;
+}
+
+gpointer
+ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoString *name, gint32 *error)
+{
+       gpointer event;
+
+       /* Need to blow away any old errors here, because code tests
+        * for ERROR_ALREADY_EXISTS on success (!) to see if an event
+        * was freshly created */
+       SetLastError (ERROR_SUCCESS);
+
+       event = name ? namedevent_create (manual, initial, mono_string_chars (name)) : event_create (manual, initial);
+
+       *error = GetLastError ();
+
+       return event;
+}
+
+gboolean
+ves_icall_System_Threading_Events_SetEvent_internal (gpointer handle)
+{
+       MonoW32HandleType type;
+       MonoW32HandleEvent *event_handle;
+       int thr_ret;
+
+       if (handle == NULL) {
+               SetLastError (ERROR_INVALID_HANDLE);
+               return(FALSE);
+       }
+
+       switch (type = mono_w32handle_get_type (handle)) {
+       case MONO_W32HANDLE_EVENT:
+       case MONO_W32HANDLE_NAMEDEVENT:
+               break;
+       default:
+               SetLastError (ERROR_INVALID_HANDLE);
+               return FALSE;
+       }
+
+       if (!mono_w32handle_lookup (handle, type, (gpointer *)&event_handle)) {
+               g_warning ("%s: error looking up %s handle %p",
+                       __func__, mono_w32handle_ops_typename (type), handle);
+               return FALSE;
+       }
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: setting %s handle %p",
+               __func__, mono_w32handle_ops_typename (type), handle);
+
+       thr_ret = mono_w32handle_lock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       if (!event_handle->manual) {
+               event_handle->set_count = 1;
+               mono_w32handle_set_signal_state (handle, TRUE, FALSE);
+       } else {
+               mono_w32handle_set_signal_state (handle, TRUE, TRUE);
+       }
+
+       thr_ret = mono_w32handle_unlock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       return TRUE;
+}
+
+gboolean
+ves_icall_System_Threading_Events_ResetEvent_internal (gpointer handle)
+{
+       MonoW32HandleType type;
+       MonoW32HandleEvent *event_handle;
+       int thr_ret;
+
+       SetLastError (ERROR_SUCCESS);
+
+       if (handle == NULL) {
+               SetLastError (ERROR_INVALID_HANDLE);
+               return(FALSE);
+       }
+
+       switch (type = mono_w32handle_get_type (handle)) {
+       case MONO_W32HANDLE_EVENT:
+       case MONO_W32HANDLE_NAMEDEVENT:
+               break;
+       default:
+               SetLastError (ERROR_INVALID_HANDLE);
+               return FALSE;
+       }
+
+       if (!mono_w32handle_lookup (handle, type, (gpointer *)&event_handle)) {
+               g_warning ("%s: error looking up %s handle %p",
+                       __func__, mono_w32handle_ops_typename (type), handle);
+               return FALSE;
+       }
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: resetting %s handle %p",
+               __func__, mono_w32handle_ops_typename (type), handle);
+
+       thr_ret = mono_w32handle_lock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       if (!mono_w32handle_issignalled (handle)) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: no need to reset %s handle %p",
+                       __func__, mono_w32handle_ops_typename (type), handle);
+       } else {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: obtained write lock on %s handle %p",
+                       __func__, mono_w32handle_ops_typename (type), handle);
+
+               mono_w32handle_set_signal_state (handle, FALSE, FALSE);
+       }
+
+       event_handle->set_count = 0;
+
+       thr_ret = mono_w32handle_unlock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       return TRUE;
+}
+
+void
+ves_icall_System_Threading_Events_CloseEvent_internal (gpointer handle)
+{
+       CloseHandle (handle);
+}
+
+gpointer
+ves_icall_System_Threading_Events_OpenEvent_internal (MonoString *name, gint32 rights G_GNUC_UNUSED, gint32 *error)
+{
+       gpointer handle;
+       gchar *utf8_name;
+
+       *error = ERROR_SUCCESS;
+
+       /* w32 seems to guarantee that opening named objects can't race each other */
+       mono_w32handle_namespace_lock ();
+
+       utf8_name = g_utf16_to_utf8 (mono_string_chars (name), -1, NULL, NULL, NULL);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening named event [%s]", __func__, utf8_name);
+
+       handle = mono_w32handle_namespace_search_handle (MONO_W32HANDLE_NAMEDEVENT, utf8_name);
+       if (handle == INVALID_HANDLE_VALUE) {
+               /* The name has already been used for a different object. */
+               *error = ERROR_INVALID_HANDLE;
+               goto cleanup;
+       } else if (!handle) {
+               /* This name doesn't exist */
+               *error = ERROR_FILE_NOT_FOUND;
+               goto cleanup;
+       }
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning named event handle %p", __func__, handle);
+
+cleanup:
+       g_free (utf8_name);
+
+       mono_w32handle_namespace_unlock ();
+
+       return handle;
+}
+
+MonoW32HandleNamespace*
+mono_w32event_get_namespace (MonoW32HandleNamedEvent *event)
+{
+       return &event->sharedns;
+}
diff --git a/mono/metadata/w32event-win32.c b/mono/metadata/w32event-win32.c
new file mode 100644 (file)
index 0000000..8659021
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * w32event-win32.c: Runtime support for managed Event on Win32
+ *
+ * Author:
+ *     Ludovic Henry (luhenry@microsoft.com)
+ *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include "w32event.h"
+
+#include <windows.h>
+#include <winbase.h>
+
+void
+mono_w32event_init (void)
+{
+}
+
+gpointer
+mono_w32event_create (gboolean manual, gboolean initial)
+{
+       return CreateEvent (NULL, manual, initial, NULL);
+}
+
+void
+mono_w32event_set (gpointer handle)
+{
+       SetEvent (handle);
+}
+
+void
+mono_w32event_reset (gpointer handle)
+{
+       ResetEvent (handle);
+}
+
+gpointer
+ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoString *name, gint32 *error)
+{
+       gpointer event;
+
+       event = CreateEvent (NULL, manual, initial, name ? mono_string_chars (name) : NULL);
+
+       *error = GetLastError ();
+
+       return event;
+}
+
+gboolean
+ves_icall_System_Threading_Events_SetEvent_internal (gpointer handle)
+{
+       return SetEvent (handle);
+}
+
+gboolean
+ves_icall_System_Threading_Events_ResetEvent_internal (gpointer handle)
+{
+       return ResetEvent (handle);
+}
+
+void
+ves_icall_System_Threading_Events_CloseEvent_internal (gpointer handle)
+{
+       CloseHandle (handle);
+}
+
+gpointer
+ves_icall_System_Threading_Events_OpenEvent_internal (MonoString *name, gint32 rights, gint32 *error)
+{
+       gpointer handle;
+
+       *error = ERROR_SUCCESS;
+
+       handle = OpenEvent (rights, FALSE, mono_string_chars (name));
+       if (!handle)
+               *error = GetLastError ();
+
+       return handle;
+}
diff --git a/mono/metadata/w32event.h b/mono/metadata/w32event.h
new file mode 100644 (file)
index 0000000..1f41b1a
--- /dev/null
@@ -0,0 +1,43 @@
+
+#ifndef _MONO_METADATA_W32EVENT_H_
+#define _MONO_METADATA_W32EVENT_H_
+
+#include <config.h>
+#include <glib.h>
+
+#include "object.h"
+#include "w32handle-namespace.h"
+
+void
+mono_w32event_init (void);
+
+gpointer
+mono_w32event_create (gboolean manual, gboolean initial);
+
+void
+mono_w32event_set (gpointer handle);
+
+void
+mono_w32event_reset (gpointer handle);
+
+gpointer
+ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoString *name, gint32 *error);
+
+gboolean
+ves_icall_System_Threading_Events_SetEvent_internal (gpointer handle);
+
+gboolean
+ves_icall_System_Threading_Events_ResetEvent_internal (gpointer handle);
+
+void
+ves_icall_System_Threading_Events_CloseEvent_internal (gpointer handle);
+
+gpointer
+ves_icall_System_Threading_Events_OpenEvent_internal (MonoString *name, gint32 rights, gint32 *error);
+
+typedef struct MonoW32HandleNamedEvent MonoW32HandleNamedEvent;
+
+MonoW32HandleNamespace*
+mono_w32event_get_namespace (MonoW32HandleNamedEvent *event);
+
+#endif /* _MONO_METADATA_W32EVENT_H_ */
diff --git a/mono/metadata/w32handle-namespace.c b/mono/metadata/w32handle-namespace.c
new file mode 100644 (file)
index 0000000..23a936b
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * w32handle-namespace.c: namespace for w32handles
+ *
+ * Author:
+ *     Ludovic Henry (luhenry@microsoft.com)
+ *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include <config.h>
+
+#ifndef HOST_WIN32
+
+#include "w32handle-namespace.h"
+
+#include "w32mutex.h"
+#include "w32semaphore.h"
+#include "w32event.h"
+#include "mono/io-layer/io-layer.h"
+#include "mono/utils/mono-logger-internals.h"
+#include "mono/utils/mono-coop-mutex.h"
+
+static MonoCoopMutex lock;
+
+void
+mono_w32handle_namespace_init (void)
+{
+       mono_coop_mutex_init (&lock);
+}
+
+void
+mono_w32handle_namespace_lock (void)
+{
+       mono_coop_mutex_lock (&lock);
+}
+
+void
+mono_w32handle_namespace_unlock (void)
+{
+       mono_coop_mutex_unlock (&lock);
+}
+
+static gboolean
+has_namespace (MonoW32HandleType type)
+{
+       switch (type) {
+       case MONO_W32HANDLE_NAMEDMUTEX:
+       case MONO_W32HANDLE_NAMEDSEM:
+       case MONO_W32HANDLE_NAMEDEVENT:
+               return TRUE;
+       default:
+               return FALSE;
+       }
+}
+
+typedef struct {
+       gpointer ret;
+       MonoW32HandleType type;
+       gchar *name;
+} NamespaceSearchHandleData;
+
+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_ops_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);
+                       search_data->ret = handle;
+               }
+
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+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_ops_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;
+}
+
+#endif
diff --git a/mono/metadata/w32handle-namespace.h b/mono/metadata/w32handle-namespace.h
new file mode 100644 (file)
index 0000000..5a25477
--- /dev/null
@@ -0,0 +1,28 @@
+
+#ifndef _MONO_METADATA_W32HANDLE_NAMESPACE_H_
+#define _MONO_METADATA_W32HANDLE_NAMESPACE_H_
+
+#include <config.h>
+#include <glib.h>
+
+#include "mono/utils/w32handle.h"
+
+#define MONO_W32HANDLE_NAMESPACE_MAX_PATH 260
+
+typedef struct {
+       gchar name [MONO_W32HANDLE_NAMESPACE_MAX_PATH + 1];
+} MonoW32HandleNamespace;
+
+void
+mono_w32handle_namespace_init (void);
+
+void
+mono_w32handle_namespace_lock (void);
+
+void
+mono_w32handle_namespace_unlock (void);
+
+gpointer
+mono_w32handle_namespace_search_handle (MonoW32HandleType type, gchar *name);
+
+#endif /* _MONO_METADATA_W32HANDLE_NAMESPACE_H_ */
\ No newline at end of file
diff --git a/mono/metadata/w32mutex-unix.c b/mono/metadata/w32mutex-unix.c
new file mode 100644 (file)
index 0000000..d7a3c03
--- /dev/null
@@ -0,0 +1,476 @@
+/*
+ * w32mutex-unix.c: Runtime support for managed Mutex on Unix
+ *
+ * Author:
+ *     Ludovic Henry (luhenry@microsoft.com)
+ *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include "w32mutex.h"
+#include "w32mutex-utils.h"
+
+#include <pthread.h>
+
+#include "w32handle-namespace.h"
+#include "mono/io-layer/io-layer.h"
+#include "mono/utils/mono-logger-internals.h"
+#include "mono/utils/mono-threads.h"
+#include "mono/utils/w32handle.h"
+
+typedef struct {
+       MonoNativeThreadId tid;
+       guint32 recursion;
+} MonoW32HandleMutex;
+
+struct MonoW32HandleNamedMutex {
+       MonoW32HandleMutex m;
+       MonoW32HandleNamespace sharedns;
+};
+
+static gboolean
+mutex_handle_own (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_ops_typename (type), handle);
+               return FALSE;
+       }
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning %s handle %p, tid %p, recursion %u",
+               __func__, mono_w32handle_ops_typename (type), handle, (gpointer) mutex_handle->tid, mutex_handle->recursion);
+
+       mono_thread_info_own_mutex (mono_thread_info_current (), handle);
+
+       mutex_handle->tid = pthread_self ();
+       mutex_handle->recursion++;
+
+       mono_w32handle_set_signal_state (handle, FALSE, FALSE);
+
+       return TRUE;
+}
+
+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_ops_typename (type), handle);
+               return FALSE;
+       }
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: testing ownership %s handle %p",
+               __func__, mono_w32handle_ops_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_ops_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, but locked %d times by %p",
+                       __func__, mono_w32handle_ops_typename (type), handle, (gpointer) pthread_self (), mutex_handle->recursion, (gpointer) mutex_handle->tid);
+               return FALSE;
+       }
+}
+
+static void mutex_signal(gpointer handle)
+{
+       ves_icall_System_Threading_Mutex_ReleaseMutex_internal (handle);
+}
+
+static gboolean mutex_own (gpointer handle)
+{
+       return mutex_handle_own (handle, MONO_W32HANDLE_MUTEX);
+}
+
+static gboolean mutex_is_owned (gpointer handle)
+{
+       
+       return mutex_handle_is_owned (handle, MONO_W32HANDLE_MUTEX);
+}
+
+static void namedmutex_signal (gpointer handle)
+{
+       ves_icall_System_Threading_Mutex_ReleaseMutex_internal (handle);
+}
+
+/* NB, always called with the shared handle lock held */
+static gboolean namedmutex_own (gpointer handle)
+{
+       return mutex_handle_own (handle, MONO_W32HANDLE_NAMEDMUTEX);
+}
+
+static gboolean namedmutex_is_owned (gpointer handle)
+{
+       return mutex_handle_is_owned (handle, MONO_W32HANDLE_NAMEDMUTEX);
+}
+
+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_ops_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_ops_typename (type), handle, mutex_handle->recursion != 0 ? "true" : "false");
+}
+
+/* The shared state is not locked when prewait methods are called */
+static void mutex_prewait (gpointer handle)
+{
+       mutex_handle_prewait (handle, MONO_W32HANDLE_MUTEX);
+}
+
+/* The shared state is not locked when prewait methods are called */
+static void namedmutex_prewait (gpointer handle)
+{
+       mutex_handle_prewait (handle, MONO_W32HANDLE_NAMEDMUTEX);
+}
+
+static void mutex_details (gpointer data)
+{
+       MonoW32HandleMutex *mut = (MonoW32HandleMutex *)data;
+       
+#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
+}
+
+static void namedmutex_details (gpointer data)
+{
+       MonoW32HandleNamedMutex *namedmut = (MonoW32HandleNamedMutex *)data;
+       
+#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
+}
+
+static const gchar* mutex_typename (void)
+{
+       return "Mutex";
+}
+
+static gsize mutex_typesize (void)
+{
+       return sizeof (MonoW32HandleMutex);
+}
+
+static const gchar* namedmutex_typename (void)
+{
+       return "N.Mutex";
+}
+
+static gsize namedmutex_typesize (void)
+{
+       return sizeof (MonoW32HandleNamedMutex);
+}
+
+void
+mono_w32mutex_init (void)
+{
+       static MonoW32HandleOps mutex_ops = {
+               NULL,                   /* close */
+               mutex_signal,           /* signal */
+               mutex_own,              /* own */
+               mutex_is_owned,         /* is_owned */
+               NULL,                   /* special_wait */
+               mutex_prewait,                  /* prewait */
+               mutex_details,  /* details */
+               mutex_typename, /* typename */
+               mutex_typesize, /* typesize */
+       };
+
+       static MonoW32HandleOps namedmutex_ops = {
+               NULL,                   /* close */
+               namedmutex_signal,      /* signal */
+               namedmutex_own,         /* own */
+               namedmutex_is_owned,    /* is_owned */
+               NULL,                   /* special_wait */
+               namedmutex_prewait,     /* prewait */
+               namedmutex_details,     /* details */
+               namedmutex_typename,    /* typename */
+               namedmutex_typesize,    /* typesize */
+       };
+
+       mono_w32handle_register_ops (MONO_W32HANDLE_MUTEX,      &mutex_ops);
+       mono_w32handle_register_ops (MONO_W32HANDLE_NAMEDMUTEX, &namedmutex_ops);
+
+       mono_w32handle_register_capabilities (MONO_W32HANDLE_MUTEX,
+               (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL | MONO_W32HANDLE_CAP_OWN));
+       mono_w32handle_register_capabilities (MONO_W32HANDLE_NAMEDMUTEX,
+               (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL | MONO_W32HANDLE_CAP_OWN));
+}
+
+static gpointer mutex_handle_create (MonoW32HandleMutex *mutex_handle, MonoW32HandleType type, gboolean owned)
+{
+       gpointer handle;
+       int thr_ret;
+
+       mutex_handle->tid = 0;
+       mutex_handle->recursion = 0;
+
+       handle = mono_w32handle_new (type, mutex_handle);
+       if (handle == INVALID_HANDLE_VALUE) {
+               g_warning ("%s: error creating %s handle",
+                       __func__, mono_w32handle_ops_typename (type));
+               SetLastError (ERROR_GEN_FAILURE);
+               return NULL;
+       }
+
+       thr_ret = mono_w32handle_lock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       if (owned)
+               mutex_handle_own (handle, type);
+       else
+               mono_w32handle_set_signal_state (handle, TRUE, FALSE);
+
+       thr_ret = mono_w32handle_unlock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created %s handle %p",
+               __func__, mono_w32handle_ops_typename (type), handle);
+
+       return handle;
+}
+
+static gpointer mutex_create (gboolean owned)
+{
+       MonoW32HandleMutex mutex_handle;
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle",
+               __func__, mono_w32handle_ops_typename (MONO_W32HANDLE_MUTEX));
+       return mutex_handle_create (&mutex_handle, MONO_W32HANDLE_MUTEX, owned);
+}
+
+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_ops_typename (MONO_W32HANDLE_NAMEDMUTEX));
+
+       /* 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);
+
+       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;
+               SetLastError (ERROR_INVALID_HANDLE);
+       } 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);
+
+               /* this is used as creating a new handle */
+               mono_w32handle_ref (handle);
+       } else {
+               /* A new named mutex */
+               MonoW32HandleNamedMutex namedmutex_handle;
+
+               strncpy (&namedmutex_handle.sharedns.name [0], utf8_name, MAX_PATH);
+               namedmutex_handle.sharedns.name [MAX_PATH] = '\0';
+
+               handle = mutex_handle_create ((MonoW32HandleMutex*) &namedmutex_handle, MONO_W32HANDLE_NAMEDMUTEX, owned);
+       }
+
+       g_free (utf8_name);
+
+       mono_w32handle_namespace_unlock ();
+
+       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 */
+       SetLastError (ERROR_SUCCESS);
+
+       if (!name) {
+               mutex = mutex_create (owned);
+       } else {
+               mutex = namedmutex_create (owned, mono_string_chars (name));
+
+               if (GetLastError () == ERROR_ALREADY_EXISTS)
+                       *created = FALSE;
+       }
+
+       return mutex;
+}
+
+MonoBoolean
+ves_icall_System_Threading_Mutex_ReleaseMutex_internal (gpointer handle)
+{
+       MonoW32HandleType type;
+       MonoW32HandleMutex *mutex_handle;
+       pthread_t tid;
+       int thr_ret;
+       gboolean ret;
+
+       if (handle == NULL) {
+               SetLastError (ERROR_INVALID_HANDLE);
+               return FALSE;
+       }
+
+       switch (type = mono_w32handle_get_type (handle)) {
+       case MONO_W32HANDLE_MUTEX:
+       case MONO_W32HANDLE_NAMEDMUTEX:
+               break;
+       default:
+               SetLastError (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_ops_typename (type), handle);
+               return FALSE;
+       }
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: releasing %s handle %p",
+               __func__, mono_w32handle_ops_typename (type), handle);
+
+       thr_ret = mono_w32handle_lock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       tid = pthread_self ();
+
+       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_ops_typename (type), handle, mutex_handle->tid, tid);
+       } else {
+               ret = TRUE;
+
+               /* OK, we own this mutex */
+               mutex_handle->recursion--;
+
+               if (mutex_handle->recursion == 0) {
+                       mono_thread_info_disown_mutex (mono_thread_info_current (), handle);
+
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking %s handle %p",
+                               __func__, mono_w32handle_ops_typename (type), handle);
+
+                       mutex_handle->tid = 0;
+                       mono_w32handle_set_signal_state (handle, TRUE, FALSE);
+               }
+       }
+
+       thr_ret = mono_w32handle_unlock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       return ret;
+}
+
+gpointer
+ves_icall_System_Threading_Mutex_OpenMutex_internal (MonoString *name, gint32 rights G_GNUC_UNUSED, gint32 *error)
+{
+       gpointer handle;
+       gchar *utf8_name;
+
+       *error = ERROR_SUCCESS;
+
+       /* w32 seems to guarantee that opening named objects can't race each other */
+       mono_w32handle_namespace_lock ();
+
+       utf8_name = g_utf16_to_utf8 (mono_string_chars (name), -1, NULL, NULL, NULL);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening named mutex [%s]",
+               __func__, utf8_name);
+
+       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. */
+               *error = ERROR_INVALID_HANDLE;
+               goto cleanup;
+       } else if (!handle) {
+               /* This name doesn't exist */
+               *error = ERROR_FILE_NOT_FOUND;
+               goto cleanup;
+       }
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning named mutex handle %p",
+               __func__, handle);
+
+cleanup:
+       g_free (utf8_name);
+
+       mono_w32handle_namespace_unlock ();
+
+       return handle;
+}
+
+void
+mono_w32mutex_abandon (gpointer handle, MonoNativeThreadId tid)
+{
+       MonoW32HandleType type;
+       MonoW32HandleMutex *mutex_handle;
+       int thr_ret;
+
+       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_warning ("%s: error looking up %s handle %p",
+                       __func__, mono_w32handle_ops_typename (type), handle);
+               return;
+       }
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: abandon %s handle %p",
+               __func__, mono_w32handle_ops_typename (type), handle);
+
+       thr_ret = mono_w32handle_lock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       if (pthread_equal (mutex_handle->tid, tid)) {
+               mutex_handle->recursion = 0;
+               mutex_handle->tid = 0;
+
+               mono_w32handle_set_signal_state (handle, TRUE, FALSE);
+
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: abandoned %s handle %p",
+                       __func__, mono_w32handle_ops_typename (type), handle);
+       }
+
+       thr_ret = mono_w32handle_unlock_handle (handle);
+       g_assert (thr_ret == 0);
+}
+
+MonoW32HandleNamespace*
+mono_w32mutex_get_namespace (MonoW32HandleNamedMutex *mutex)
+{
+       return &mutex->sharedns;
+}
diff --git a/mono/metadata/w32mutex-utils.h b/mono/metadata/w32mutex-utils.h
new file mode 100644 (file)
index 0000000..a7bad8c
--- /dev/null
@@ -0,0 +1,20 @@
+
+/* This is just a hack so we can call mono_w32mutex_abandon
+ * from mono/utils/mono-threads-posix.c, without importing
+ * the whole object.h
+ * In the best of all world, mutex owning + disowning + abandoning
+ * should be done in metadata/ */
+
+#ifndef _MONO_METADATA_W32MUTEX_UTILS_H_
+#define _MONO_METADATA_W32MUTEX_UTILS_H_
+
+#include <config.h>
+#include <glib.h>
+
+#include "mono/utils/mono-threads.h"
+
+void
+mono_w32mutex_abandon (gpointer handle, MonoNativeThreadId tid);
+
+#endif /* _MONO_METADATA_W32MUTEX_UTILS_H_ */
+
diff --git a/mono/metadata/w32mutex-win32.c b/mono/metadata/w32mutex-win32.c
new file mode 100644 (file)
index 0000000..6f967e8
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * w32mutex-win32.c: Runtime support for managed Mutex on Win32
+ *
+ * Author:
+ *     Ludovic Henry (luhenry@microsoft.com)
+ *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include "w32mutex.h"
+
+#include <windows.h>
+#include <winbase.h>
+
+void
+mono_w32mutex_init (void)
+{
+}
+
+gpointer
+ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoString *name, MonoBoolean *created)
+{
+       HANDLE mutex;
+
+       *created = TRUE;
+
+       if (!name) {
+               mutex = CreateMutex (NULL, owned, NULL);
+       } else {
+               mutex = CreateMutex (NULL, owned, mono_string_chars (name));
+
+               if (GetLastError () == ERROR_ALREADY_EXISTS)
+                       *created = FALSE;
+       }
+
+       return mutex;
+}
+
+MonoBoolean
+ves_icall_System_Threading_Mutex_ReleaseMutex_internal (gpointer handle)
+{
+       return ReleaseMutex (handle);
+}
+
+gpointer
+ves_icall_System_Threading_Mutex_OpenMutex_internal (MonoString *name, gint32 rights, gint32 *error)
+{
+       HANDLE ret;
+
+       *error = ERROR_SUCCESS;
+
+       ret = OpenMutex (rights, FALSE, mono_string_chars (name));
+       if (!ret)
+               *error = GetLastError ();
+
+       return ret;
+}
diff --git a/mono/metadata/w32mutex.h b/mono/metadata/w32mutex.h
new file mode 100644 (file)
index 0000000..3c63619
--- /dev/null
@@ -0,0 +1,28 @@
+
+#ifndef _MONO_METADATA_W32MUTEX_H_
+#define _MONO_METADATA_W32MUTEX_H_
+
+#include <config.h>
+#include <glib.h>
+
+#include "object.h"
+#include "w32handle-namespace.h"
+
+void
+mono_w32mutex_init (void);
+
+gpointer
+ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoString *name, MonoBoolean *created);
+
+MonoBoolean
+ves_icall_System_Threading_Mutex_ReleaseMutex_internal (gpointer handle);
+
+gpointer
+ves_icall_System_Threading_Mutex_OpenMutex_internal (MonoString *name, gint32 rights, gint32 *error);
+
+typedef struct MonoW32HandleNamedMutex MonoW32HandleNamedMutex;
+
+MonoW32HandleNamespace*
+mono_w32mutex_get_namespace (MonoW32HandleNamedMutex *mutex);
+
+#endif /* _MONO_METADATA_W32MUTEX_H_ */
diff --git a/mono/metadata/w32semaphore-unix.c b/mono/metadata/w32semaphore-unix.c
new file mode 100644 (file)
index 0000000..d21ef97
--- /dev/null
@@ -0,0 +1,357 @@
+/*
+ * w32semaphore-unix.c: Runtime support for managed Semaphore on Unix
+ *
+ * Author:
+ *     Ludovic Henry (luhenry@microsoft.com)
+ *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include "w32semaphore.h"
+
+#include "w32handle-namespace.h"
+#include "mono/io-layer/io-layer.h"
+#include "mono/utils/mono-logger-internals.h"
+#include "mono/utils/w32handle.h"
+
+typedef struct {
+       guint32 val;
+       gint32 max;
+} MonoW32HandleSemaphore;
+
+struct MonoW32HandleNamedSemaphore {
+       MonoW32HandleSemaphore s;
+       MonoW32HandleNamespace sharedns;
+};
+
+static gboolean sem_handle_own (gpointer handle, MonoW32HandleType type)
+{
+       MonoW32HandleSemaphore *sem_handle;
+
+       if (!mono_w32handle_lookup (handle, type, (gpointer *)&sem_handle)) {
+               g_warning ("%s: error looking up %s handle %p",
+                       __func__, mono_w32handle_ops_typename (type), handle);
+               return FALSE;
+       }
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning %s handle %p",
+               __func__, mono_w32handle_ops_typename (type), handle);
+
+       sem_handle->val--;
+
+       if (sem_handle->val == 0)
+               mono_w32handle_set_signal_state (handle, FALSE, FALSE);
+
+       return TRUE;
+}
+
+static void sema_signal(gpointer handle)
+{
+       ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal(handle, 1, NULL);
+}
+
+static gboolean sema_own (gpointer handle)
+{
+       return sem_handle_own (handle, MONO_W32HANDLE_SEM);
+}
+
+static void namedsema_signal (gpointer handle)
+{
+       ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (handle, 1, NULL);
+}
+
+/* NB, always called with the shared handle lock held */
+static gboolean namedsema_own (gpointer handle)
+{
+       return sem_handle_own (handle, MONO_W32HANDLE_NAMEDSEM);
+}
+
+static void sema_details (gpointer data)
+{
+       MonoW32HandleSemaphore *sem = (MonoW32HandleSemaphore *)data;
+       g_print ("val: %5u, max: %5d", sem->val, sem->max);
+}
+
+static void namedsema_details (gpointer data)
+{
+       MonoW32HandleNamedSemaphore *namedsem = (MonoW32HandleNamedSemaphore *)data;
+       g_print ("val: %5u, max: %5d, name: \"%s\"", namedsem->s.val, namedsem->s.max, namedsem->sharedns.name);
+}
+
+static const gchar* sema_typename (void)
+{
+       return "Semaphore";
+}
+
+static gsize sema_typesize (void)
+{
+       return sizeof (MonoW32HandleSemaphore);
+}
+
+static const gchar* namedsema_typename (void)
+{
+       return "N.Semaphore";
+}
+
+static gsize namedsema_typesize (void)
+{
+       return sizeof (MonoW32HandleNamedSemaphore);
+}
+
+void
+mono_w32semaphore_init (void)
+{
+       static MonoW32HandleOps sem_ops = {
+               NULL,                   /* close */
+               sema_signal,            /* signal */
+               sema_own,               /* own */
+               NULL,                   /* is_owned */
+               NULL,                   /* special_wait */
+               NULL,                   /* prewait */
+               sema_details,   /* details */
+               sema_typename,  /* typename */
+               sema_typesize,  /* typesize */
+       };
+
+       static MonoW32HandleOps namedsem_ops = {
+               NULL,                   /* close */
+               namedsema_signal,       /* signal */
+               namedsema_own,          /* own */
+               NULL,                   /* is_owned */
+               NULL,                   /* special_wait */
+               NULL,                   /* prewait */
+               namedsema_details,      /* details */
+               namedsema_typename,     /* typename */
+               namedsema_typesize,     /* typesize */
+       };
+
+       mono_w32handle_register_ops (MONO_W32HANDLE_SEM,      &sem_ops);
+       mono_w32handle_register_ops (MONO_W32HANDLE_NAMEDSEM, &namedsem_ops);
+
+       mono_w32handle_register_capabilities (MONO_W32HANDLE_SEM,
+               (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
+       mono_w32handle_register_capabilities (MONO_W32HANDLE_NAMEDSEM,
+               (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
+}
+
+static gpointer
+sem_handle_create (MonoW32HandleSemaphore *sem_handle, MonoW32HandleType type, gint32 initial, gint32 max)
+{
+       gpointer handle;
+       int thr_ret;
+
+       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_ops_typename (type));
+               SetLastError (ERROR_GEN_FAILURE);
+               return NULL;
+       }
+
+       thr_ret = mono_w32handle_lock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       if (initial != 0)
+               mono_w32handle_set_signal_state (handle, TRUE, FALSE);
+
+       thr_ret = mono_w32handle_unlock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created %s handle %p",
+               __func__, mono_w32handle_ops_typename (type), handle);
+
+       return handle;
+}
+
+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_ops_typename (MONO_W32HANDLE_SEM), initial, max);
+       return sem_handle_create (&sem_handle, MONO_W32HANDLE_SEM, initial, max);
+}
+
+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_ops_typename (MONO_W32HANDLE_NAMEDSEM), initial, max, 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);
+
+               /* this is used as creating a new handle */
+               mono_w32handle_ref (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;
+}
+
+gpointer
+ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 initialCount, gint32 maximumCount, MonoString *name, gint32 *error)
+{ 
+       gpointer sem;
+
+       if (maximumCount <= 0) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: maximumCount <= 0", __func__);
+
+               *error = ERROR_INVALID_PARAMETER;
+               return NULL;
+       }
+
+       if (initialCount > maximumCount || initialCount < 0) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: initialCount > maximumCount or < 0", __func__);
+
+               *error = ERROR_INVALID_PARAMETER;
+               return NULL;
+       }
+
+       /* Need to blow away any old errors here, because code tests
+        * for ERROR_ALREADY_EXISTS on success (!) to see if a
+        * semaphore was freshly created
+        */
+       SetLastError (ERROR_SUCCESS);
+
+       if (!name)
+               sem = sem_create (initialCount, maximumCount);
+       else
+               sem = namedsem_create (initialCount, maximumCount, mono_string_chars (name));
+
+       *error = GetLastError ();
+
+       return sem;
+}
+
+MonoBoolean
+ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (gpointer handle, gint32 releaseCount, gint32 *prevcount)
+{
+       MonoW32HandleType type;
+       MonoW32HandleSemaphore *sem_handle;
+       int thr_ret;
+       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_ops_typename (type), handle);
+
+       thr_ret = mono_w32handle_lock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       /* 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_ops_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_ops_typename (type), handle, sem_handle->val, releaseCount, sem_handle->max);
+
+               sem_handle->val += releaseCount;
+               mono_w32handle_set_signal_state (handle, TRUE, TRUE);
+
+               ret = TRUE;
+       }
+
+       thr_ret = mono_w32handle_unlock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       return ret;
+}
+
+gpointer
+ves_icall_System_Threading_Semaphore_OpenSemaphore_internal (MonoString *name, gint32 rights, gint32 *error)
+{
+       gpointer handle;
+       gchar *utf8_name;
+
+       *error = ERROR_SUCCESS;
+
+       /* w32 seems to guarantee that opening named objects can't race each other */
+       mono_w32handle_namespace_lock ();
+
+       utf8_name = g_utf16_to_utf8 (mono_string_chars (name), -1, NULL, NULL, NULL);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening named sem [%s]", __func__, utf8_name);
+
+       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. */
+               *error = ERROR_INVALID_HANDLE;
+               goto cleanup;
+       } else if (!handle) {
+               /* This name doesn't exist */
+               *error = ERROR_FILE_NOT_FOUND;
+               goto cleanup;
+       }
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning named sem handle %p", __func__, handle);
+
+cleanup:
+       g_free (utf8_name);
+
+       mono_w32handle_namespace_unlock ();
+
+       return handle;
+}
+
+MonoW32HandleNamespace*
+mono_w32semaphore_get_namespace (MonoW32HandleNamedSemaphore *semaphore)
+{
+       return &semaphore->sharedns;
+}
diff --git a/mono/metadata/w32semaphore-win32.c b/mono/metadata/w32semaphore-win32.c
new file mode 100644 (file)
index 0000000..d7c6b62
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * w32semaphore-win32.c: Runtime support for managed Semaphore on Win32
+ *
+ * Author:
+ *     Ludovic Henry (luhenry@microsoft.com)
+ *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include "w32semaphore.h"
+
+#include <windows.h>
+#include <winbase.h>
+
+void
+mono_w32semaphore_init (void)
+{
+}
+
+gpointer
+ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 initialCount, gint32 maximumCount, MonoString *name, gint32 *error)
+{ 
+       HANDLE sem;
+
+       sem = CreateSemaphore (NULL, initialCount, maximumCount, name ? mono_string_chars (name) : NULL);
+
+       *error = GetLastError ();
+
+       return sem;
+}
+
+MonoBoolean
+ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (gpointer handle, gint32 releaseCount, gint32 *prevcount)
+{ 
+       return ReleaseSemaphore (handle, releaseCount, prevcount);
+}
+
+gpointer
+ves_icall_System_Threading_Semaphore_OpenSemaphore_internal (MonoString *name, gint32 rights, gint32 *error)
+{
+       HANDLE sem;
+
+       sem = OpenSemaphore (rights, FALSE, mono_string_chars (name));
+
+       *error = GetLastError ();
+
+       return sem;
+}
\ No newline at end of file
diff --git a/mono/metadata/w32semaphore.h b/mono/metadata/w32semaphore.h
new file mode 100644 (file)
index 0000000..789dfbe
--- /dev/null
@@ -0,0 +1,28 @@
+
+#ifndef _MONO_METADATA_W32SEMAPHORE_H_
+#define _MONO_METADATA_W32SEMAPHORE_H_
+
+#include <config.h>
+#include <glib.h>
+
+#include "object.h"
+#include "w32handle-namespace.h"
+
+void
+mono_w32semaphore_init (void);
+
+gpointer
+ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 initialCount, gint32 maximumCount, MonoString *name, gint32 *error);
+
+MonoBoolean
+ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (gpointer handle, gint32 releaseCount, gint32 *prevcount);
+
+gpointer
+ves_icall_System_Threading_Semaphore_OpenSemaphore_internal (MonoString *name, gint32 rights, gint32 *error);
+
+typedef struct MonoW32HandleNamedSemaphore MonoW32HandleNamedSemaphore;
+
+MonoW32HandleNamespace*
+mono_w32semaphore_get_namespace (MonoW32HandleNamedSemaphore *semaphore);
+
+#endif /* _MONO_METADATA_W32SEMAPHORE_H_ */
index 42557975a9ec43f4b81137df4c1893b30907ef67..4b9f5d393f5e79fb7ee9dc489f7fe8b00a0e7f69 100644 (file)
@@ -18,6 +18,7 @@
 #include <mono/utils/mono-threads-posix-signals.h>
 #include <mono/utils/mono-coop-semaphore.h>
 #include <mono/metadata/gc-internals.h>
+#include <mono/metadata/w32mutex-utils.h>
 #include <mono/utils/w32handle.h>
 
 #include <errno.h>
@@ -291,7 +292,6 @@ mono_threads_platform_set_exited (MonoThreadInfo *info)
 {
        gpointer mutex_handle;
        int i, thr_ret;
-       pid_t pid;
        pthread_t tid;
 
        g_assert (info->handle);
@@ -301,12 +301,11 @@ mono_threads_platform_set_exited (MonoThreadInfo *info)
        if (mono_w32handle_get_type (info->handle) == MONO_W32HANDLE_UNUSED)
                g_error ("%s: handle %p thread %p has already exited, it's handle type is 'unused'", __func__, info->handle, mono_thread_info_get_tid (info));
 
-       pid = wapi_getpid ();
        tid = pthread_self ();
 
        for (i = 0; i < info->owned_mutexes->len; i++) {
                mutex_handle = g_ptr_array_index (info->owned_mutexes, i);
-               wapi_mutex_abandon (mutex_handle, pid, tid);
+               mono_w32mutex_abandon (mutex_handle, tid);
                mono_thread_info_disown_mutex (info, mutex_handle);
        }
 
index 41f6439154b8065c50523f175f48f0c55c97835b..78517bc7c3aece3e8f2b96fc3d519c791872fe43 100644 (file)
@@ -26,6 +26,9 @@
     <ClCompile Include="..\mono\metadata\class.c" />\r
     <ClCompile Include="..\mono\metadata\cominterop.c" />\r
     <ClCompile Include="..\mono\metadata\console-win32.c" />\r
+    <ClCompile Include="..\mono\metadata\w32mutex-win32.c" />\r
+    <ClCompile Include="..\mono\metadata\w32semaphore-win32.c" />\r
+    <ClCompile Include="..\mono\metadata\w32event-win32.c" />\r
     <ClCompile Include="..\mono\metadata\coree.c" />\r
     <ClCompile Include="..\mono\metadata\custom-attrs.c" />\r
     <ClCompile Include="..\mono\metadata\debug-helpers.c" />\r
index 13f50fb2be4cdd5171a246f051f07b3b60db1da9..ba4d25f1ba94d8e9c6028b819c66bbfb4f414532 100644 (file)
     <ClCompile Include="..\mono\metadata\console-win32.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\w32mutex-win32.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\w32semaphore-win32.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\w32event-win32.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\mono\metadata\coree.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r