X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fw32semaphore-unix.c;h=0db4d5946fdc9f854d0c465c0437e1c4fabb93dd;hb=HEAD;hp=2537853943d81bb831a755c881cab5fb8b2f908a;hpb=16ada3424ad720db1411ff40131abd905ddacc63;p=mono.git diff --git a/mono/metadata/w32semaphore-unix.c b/mono/metadata/w32semaphore-unix.c index 2537853943d..0db4d5946fd 100644 --- a/mono/metadata/w32semaphore-unix.c +++ b/mono/metadata/w32semaphore-unix.c @@ -1,5 +1,6 @@ -/* - * w32semaphore-unix.c: Runtime support for managed Semaphore on Unix +/** + * \file + * Runtime support for managed Semaphore on Unix * * Author: * Ludovic Henry (luhenry@microsoft.com) @@ -26,6 +27,24 @@ struct MonoW32HandleNamedSemaphore { MonoW32HandleNamespace sharedns; }; +static void sem_handle_signal (gpointer handle, MonoW32HandleType type, MonoW32HandleSemaphore *sem_handle) +{ + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: signalling %s handle %p", + __func__, mono_w32handle_get_typename (type), handle); + + /* No idea why max is signed, but thats the spec :-( */ + if (sem_handle->val + 1 > (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_get_typename (type), handle, sem_handle->val, 1, sem_handle->max); + } else { + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s handle %p val %d count %d max %d", + __func__, mono_w32handle_get_typename (type), handle, sem_handle->val, 1, sem_handle->max); + + sem_handle->val += 1; + mono_w32handle_set_signal_state (handle, TRUE, TRUE); + } +} + static gboolean sem_handle_own (gpointer handle, MonoW32HandleType type, gboolean *abandoned) { MonoW32HandleSemaphore *sem_handle; @@ -49,9 +68,9 @@ static gboolean sem_handle_own (gpointer handle, MonoW32HandleType type, gboolea return TRUE; } -static void sema_signal(gpointer handle) +static void sema_signal(gpointer handle, gpointer handle_specific) { - ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal(handle, 1, NULL); + sem_handle_signal (handle, MONO_W32HANDLE_SEM, (MonoW32HandleSemaphore*) handle_specific); } static gboolean sema_own (gpointer handle, gboolean *abandoned) @@ -59,9 +78,9 @@ static gboolean sema_own (gpointer handle, gboolean *abandoned) return sem_handle_own (handle, MONO_W32HANDLE_SEM, abandoned); } -static void namedsema_signal (gpointer handle) +static void namedsema_signal (gpointer handle, gpointer handle_specific) { - ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (handle, 1, NULL); + sem_handle_signal (handle, MONO_W32HANDLE_NAMEDSEM, (MonoW32HandleSemaphore*) handle_specific); } /* NB, always called with the shared handle lock held */ @@ -188,7 +207,8 @@ namedsem_create (gint32 initial, gint32 max, const gunichar2 *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); + glong utf8_len = 0; + utf8_name = g_utf16_to_utf8 (name, -1, NULL, &utf8_len, 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); @@ -206,8 +226,9 @@ namedsem_create (gint32 initial, gint32 max, const gunichar2 *name) /* A new named semaphore */ MonoW32HandleNamedSemaphore namedsem_handle; - strncpy (&namedsem_handle.sharedns.name [0], utf8_name, MAX_PATH); - namedsem_handle.sharedns.name [MAX_PATH] = '\0'; + size_t len = utf8_len < MAX_PATH ? utf8_len : MAX_PATH; + memcpy (&namedsem_handle.sharedns.name [0], utf8_name, len); + namedsem_handle.sharedns.name [len] = '\0'; handle = sem_handle_create ((MonoW32HandleSemaphore*) &namedsem_handle, MONO_W32HANDLE_NAMEDSEM, initial, max); }