X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fw32event-unix.c;h=37ec577a6b02fb17f37d0a5f02813a867cb08f6a;hb=HEAD;hp=5644ce7d27b1eb708aa47933e1acca5b0be7b44d;hpb=e2602e1d4ae8e83d969b0230d5175f78e06c3b41;p=mono.git diff --git a/mono/metadata/w32event-unix.c b/mono/metadata/w32event-unix.c index 5644ce7d27b..37ec577a6b0 100644 --- a/mono/metadata/w32event-unix.c +++ b/mono/metadata/w32event-unix.c @@ -1,5 +1,6 @@ -/* - * w32event-unix.c: Runtime support for managed Event on Unix +/** + * \file + * Runtime support for managed Event on Unix * * Author: * Ludovic Henry (luhenry@microsoft.com) @@ -9,10 +10,21 @@ #include "w32event.h" +#include "w32error.h" #include "w32handle-namespace.h" -#include "mono/io-layer/io-layer.h" +#include "mono/utils/mono-error-internals.h" #include "mono/utils/mono-logger-internals.h" -#include "mono/utils/w32handle.h" +#include "mono/metadata/handle.h" +#include "mono/metadata/object-internals.h" +#include "mono/metadata/w32handle.h" + +#define MAX_PATH 260 + +static gpointer +mono_w32event_create_full (MonoBoolean manual, MonoBoolean initial, const gchar *name, gint32 *err); + +static gpointer +mono_w32event_open (const gchar *utf8_name, gint32 rights G_GNUC_UNUSED, gint32 *error); typedef struct { gboolean manual; @@ -24,22 +36,35 @@ struct MonoW32HandleNamedEvent { MonoW32HandleNamespace sharedns; }; -static gboolean event_handle_own (gpointer handle, MonoW32HandleType type, guint32 *statuscode) +static void event_handle_signal (gpointer handle, MonoW32HandleType type, MonoW32HandleEvent *event_handle) +{ + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: signalling %s handle %p", + __func__, mono_w32handle_get_typename (type), handle); + + 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); + } +} + +static gboolean event_handle_own (gpointer handle, MonoW32HandleType type, gboolean *abandoned) { MonoW32HandleEvent *event_handle; gboolean ok; - *statuscode = WAIT_OBJECT_0; + *abandoned = FALSE; 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); + __func__, mono_w32handle_get_typename (type), handle); return FALSE; } mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning %s handle %p", - __func__, mono_w32handle_ops_typename (type), handle); + __func__, mono_w32handle_get_typename (type), handle); if (!event_handle->manual) { g_assert (event_handle->set_count > 0); @@ -52,25 +77,25 @@ static gboolean event_handle_own (gpointer handle, MonoW32HandleType type, guint return TRUE; } -static void event_signal(gpointer handle) +static void event_signal(gpointer handle, gpointer handle_specific) { - ves_icall_System_Threading_Events_SetEvent_internal (handle); + event_handle_signal (handle, MONO_W32HANDLE_EVENT, (MonoW32HandleEvent*) handle_specific); } -static gboolean event_own (gpointer handle, guint32 *statuscode) +static gboolean event_own (gpointer handle, gboolean *abandoned) { - return event_handle_own (handle, MONO_W32HANDLE_EVENT, statuscode); + return event_handle_own (handle, MONO_W32HANDLE_EVENT, abandoned); } -static void namedevent_signal (gpointer handle) +static void namedevent_signal (gpointer handle, gpointer handle_specific) { - ves_icall_System_Threading_Events_SetEvent_internal (handle); + event_handle_signal (handle, MONO_W32HANDLE_NAMEDEVENT, (MonoW32HandleEvent*) handle_specific); } /* NB, always called with the shared handle lock held */ -static gboolean namedevent_own (gpointer handle, guint32 *statuscode) +static gboolean namedevent_own (gpointer handle, gboolean *abandoned) { - return event_handle_own (handle, MONO_W32HANDLE_NAMEDEVENT, statuscode); + return event_handle_own (handle, MONO_W32HANDLE_NAMEDEVENT, abandoned); } static void event_details (gpointer data) @@ -149,13 +174,19 @@ mono_w32event_create (gboolean manual, gboolean initial) gpointer handle; gint32 error; - handle = ves_icall_System_Threading_Events_CreateEvent_internal (manual, initial, NULL, &error); + handle = mono_w32event_create_full (manual, initial, NULL, &error); if (error != ERROR_SUCCESS) g_assert (!handle); return handle; } +gboolean +mono_w32event_close (gpointer handle) +{ + return mono_w32handle_close (handle); +} + void mono_w32event_set (gpointer handle) { @@ -171,7 +202,6 @@ mono_w32event_reset (gpointer 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; @@ -179,22 +209,20 @@ static gpointer event_handle_create (MonoW32HandleEvent *event_handle, MonoW32Ha 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); + __func__, mono_w32handle_get_typename (type)); + mono_w32error_set_last (ERROR_GEN_FAILURE); return NULL; } - thr_ret = mono_w32handle_lock_handle (handle); - g_assert (thr_ret == 0); + mono_w32handle_lock_handle (handle); if (initial) mono_w32handle_set_signal_state (handle, TRUE, FALSE); - thr_ret = mono_w32handle_unlock_handle (handle); - g_assert (thr_ret == 0); + mono_w32handle_unlock_handle (handle); mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created %s handle %p", - __func__, mono_w32handle_ops_typename (type), handle); + __func__, mono_w32handle_get_typename (type), handle); return handle; } @@ -203,76 +231,84 @@ 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)); + __func__, mono_w32handle_get_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) +static gpointer namedevent_create (gboolean manual, gboolean initial, const gchar *utf8_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)); + __func__, mono_w32handle_get_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); + glong utf8_len = strlen (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. */ handle = NULL; - SetLastError (ERROR_INVALID_HANDLE); + mono_w32error_set_last (ERROR_INVALID_HANDLE); } else if (handle) { /* Not an error, but this is how the caller is informed that the event wasn't freshly created */ - SetLastError (ERROR_ALREADY_EXISTS); + mono_w32error_set_last (ERROR_ALREADY_EXISTS); /* mono_w32handle_namespace_search_handle already adds a ref to the 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'; + size_t len = utf8_len < MAX_PATH ? utf8_len : MAX_PATH; + memcpy (&namedevent_handle.sharedns.name [0], utf8_name, len); + namedevent_handle.sharedns.name [len] = '\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) +mono_w32event_create_full (MonoBoolean manual, MonoBoolean initial, const gchar *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); + mono_w32error_set_last (ERROR_SUCCESS); - event = name ? namedevent_create (manual, initial, mono_string_chars (name)) : event_create (manual, initial); + event = name ? namedevent_create (manual, initial, name) : event_create (manual, initial); - *error = GetLastError (); + *error = mono_w32error_get_last (); return event; } +gpointer +ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoStringHandle name, gint32 *err, MonoError *error) +{ + error_init (error); + gchar *utf8_name = mono_string_handle_to_utf8 (name, error); + return_val_if_nok (error, NULL); + gpointer result = mono_w32event_create_full (manual, initial, utf8_name, err); + g_free (utf8_name); + return result; +} + 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); + mono_w32error_set_last (ERROR_INVALID_HANDLE); return(FALSE); } @@ -281,21 +317,20 @@ ves_icall_System_Threading_Events_SetEvent_internal (gpointer handle) case MONO_W32HANDLE_NAMEDEVENT: break; default: - SetLastError (ERROR_INVALID_HANDLE); + mono_w32error_set_last (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); + __func__, mono_w32handle_get_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); + __func__, mono_w32handle_get_typename (type), handle); - thr_ret = mono_w32handle_lock_handle (handle); - g_assert (thr_ret == 0); + mono_w32handle_lock_handle (handle); if (!event_handle->manual) { event_handle->set_count = 1; @@ -304,8 +339,7 @@ ves_icall_System_Threading_Events_SetEvent_internal (gpointer handle) mono_w32handle_set_signal_state (handle, TRUE, TRUE); } - thr_ret = mono_w32handle_unlock_handle (handle); - g_assert (thr_ret == 0); + mono_w32handle_unlock_handle (handle); return TRUE; } @@ -315,12 +349,11 @@ ves_icall_System_Threading_Events_ResetEvent_internal (gpointer handle) { MonoW32HandleType type; MonoW32HandleEvent *event_handle; - int thr_ret; - SetLastError (ERROR_SUCCESS); + mono_w32error_set_last (ERROR_SUCCESS); if (handle == NULL) { - SetLastError (ERROR_INVALID_HANDLE); + mono_w32error_set_last (ERROR_INVALID_HANDLE); return(FALSE); } @@ -329,36 +362,34 @@ ves_icall_System_Threading_Events_ResetEvent_internal (gpointer handle) case MONO_W32HANDLE_NAMEDEVENT: break; default: - SetLastError (ERROR_INVALID_HANDLE); + mono_w32error_set_last (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); + __func__, mono_w32handle_get_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); + __func__, mono_w32handle_get_typename (type), handle); - thr_ret = mono_w32handle_lock_handle (handle); - g_assert (thr_ret == 0); + mono_w32handle_lock_handle (handle); 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); + __func__, mono_w32handle_get_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); + __func__, mono_w32handle_get_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); + mono_w32handle_unlock_handle (handle); return TRUE; } @@ -366,22 +397,29 @@ ves_icall_System_Threading_Events_ResetEvent_internal (gpointer handle) void ves_icall_System_Threading_Events_CloseEvent_internal (gpointer handle) { - CloseHandle (handle); + mono_w32handle_close (handle); } gpointer -ves_icall_System_Threading_Events_OpenEvent_internal (MonoString *name, gint32 rights G_GNUC_UNUSED, gint32 *error) +ves_icall_System_Threading_Events_OpenEvent_internal (MonoStringHandle name, gint32 rights G_GNUC_UNUSED, gint32 *err, MonoError *error) { - gpointer handle; - gchar *utf8_name; + error_init (error); + gchar *utf8_name = mono_string_handle_to_utf8 (name, error); + return_val_if_nok (error, NULL); + gpointer handle = mono_w32event_open (utf8_name, rights, err); + g_free (utf8_name); + return handle; +} +gpointer +mono_w32event_open (const gchar *utf8_name, gint32 rights G_GNUC_UNUSED, gint32 *error) +{ + gpointer handle; *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); @@ -398,8 +436,6 @@ ves_icall_System_Threading_Events_OpenEvent_internal (MonoString *name, gint32 r 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;