Ooops, gen-65 is broken, not test-65.
[mono.git] / mono / io-layer / events.c
index e07afe653f131bc6d0e0d13fa0acb843975a903f..c99175dd34224c2e8c9cae062487d8fdd5041036 100644 (file)
@@ -14,7 +14,6 @@
 
 #include <mono/io-layer/wapi.h>
 #include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/wait-private.h>
 #include <mono/io-layer/handles-private.h>
 #include <mono/io-layer/misc-private.h>
 
@@ -36,7 +35,7 @@ struct _WapiHandleOps _wapi_event_ops = {
        NULL,                   /* is_owned */
 };
 
-static pthread_once_t event_ops_once=PTHREAD_ONCE_INIT;
+static mono_once_t event_ops_once=MONO_ONCE_INIT;
 
 static void event_ops_init (void)
 {
@@ -86,7 +85,11 @@ static void event_own (gpointer handle)
 #endif
 
        if(event_handle->manual==FALSE) {
-               _wapi_handle_set_signal_state (handle, FALSE, FALSE);
+               g_assert (event_handle->set_count > 0);
+               
+               if (--event_handle->set_count == 0) {
+                       _wapi_handle_set_signal_state (handle, FALSE, FALSE);
+               }
        }
 }
 
@@ -111,13 +114,15 @@ static void event_own (gpointer handle)
  * Return value: A new handle, or %NULL on error.
  */
 gpointer CreateEvent(WapiSecurityAttributes *security G_GNUC_UNUSED, gboolean manual,
-                    gboolean initial, const guchar *name G_GNUC_UNUSED)
+                    gboolean initial, const gunichar2 *name G_GNUC_UNUSED)
 {
        struct _WapiHandle_event *event_handle;
        gpointer handle;
        gboolean ok;
+       gpointer ret = NULL;
+       int thr_ret;
        
-       pthread_once (&event_ops_once, event_ops_init);
+       mono_once (&event_ops_once, event_ops_init);
 
        handle=_wapi_handle_new (WAPI_HANDLE_EVENT);
        if(handle==_WAPI_HANDLE_INVALID) {
@@ -126,20 +131,28 @@ gpointer CreateEvent(WapiSecurityAttributes *security G_GNUC_UNUSED, gboolean ma
                return(NULL);
        }
        
-       _wapi_handle_lock_handle (handle);
+       pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
+                             handle);
+       thr_ret = _wapi_handle_lock_handle (handle);
+       g_assert (thr_ret == 0);
        
        ok=_wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
                                (gpointer *)&event_handle, NULL);
        if(ok==FALSE) {
                g_warning (G_GNUC_PRETTY_FUNCTION
                           ": error looking up event handle %p", handle);
-               _wapi_handle_unlock_handle (handle);
-               return(NULL);
+               goto cleanup;
        }
+       ret = handle;
        
        event_handle->manual=manual;
+       event_handle->set_count = 0;
 
        if(initial==TRUE) {
+               if (manual == FALSE) {
+                       event_handle->set_count = 1;
+               }
+               
                _wapi_handle_set_signal_state (handle, TRUE, FALSE);
        }
        
@@ -148,9 +161,13 @@ gpointer CreateEvent(WapiSecurityAttributes *security G_GNUC_UNUSED, gboolean ma
                  handle);
 #endif
 
-       _wapi_handle_unlock_handle (handle);
+cleanup:
+       thr_ret = _wapi_handle_unlock_handle (handle);
+       g_assert (thr_ret == 0);
        
-       return(handle);
+       pthread_cleanup_pop (0);
+
+       return(ret);
 }
 
 /**
@@ -172,6 +189,7 @@ gboolean PulseEvent(gpointer handle)
 {
        struct _WapiHandle_event *event_handle;
        gboolean ok;
+       int thr_ret;
        
        ok=_wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
                                (gpointer *)&event_handle, NULL);
@@ -181,7 +199,10 @@ gboolean PulseEvent(gpointer handle)
                return(FALSE);
        }
        
-       _wapi_handle_lock_handle (handle);
+       pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
+                             handle);
+       thr_ret = _wapi_handle_lock_handle (handle);
+       g_assert (thr_ret == 0);
 
 #ifdef DEBUG
        g_message(G_GNUC_PRETTY_FUNCTION ": Pulsing event handle %p", handle);
@@ -190,10 +211,14 @@ gboolean PulseEvent(gpointer handle)
        if(event_handle->manual==TRUE) {
                _wapi_handle_set_signal_state (handle, TRUE, TRUE);
        } else {
+               event_handle->set_count++;
                _wapi_handle_set_signal_state (handle, TRUE, FALSE);
        }
 
-       _wapi_handle_unlock_handle (handle);
+       thr_ret = _wapi_handle_unlock_handle (handle);
+       g_assert (thr_ret == 0);
+       
+       pthread_cleanup_pop (0);
        
        if(event_handle->manual==TRUE) {
                /* For a manual-reset event, we're about to try and
@@ -213,9 +238,15 @@ gboolean PulseEvent(gpointer handle)
                          ": Obtained write lock on event handle %p", handle);
 #endif
 
-               _wapi_handle_lock_handle (handle);
+               pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle, handle);
+               thr_ret = _wapi_handle_lock_handle (handle);
+               g_assert (thr_ret == 0);
+               
                _wapi_handle_set_signal_state (handle, FALSE, FALSE);
-               _wapi_handle_unlock_handle (handle);
+
+               thr_ret = _wapi_handle_unlock_handle (handle);
+               g_assert (thr_ret == 0);
+               pthread_cleanup_pop (0);
        }
 
        return(TRUE);
@@ -234,6 +265,7 @@ gboolean ResetEvent(gpointer handle)
 {
        struct _WapiHandle_event *event_handle;
        gboolean ok;
+       int thr_ret;
        
        ok=_wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
                                (gpointer *)&event_handle, NULL);
@@ -248,26 +280,31 @@ gboolean ResetEvent(gpointer handle)
                  handle);
 #endif
 
-       _wapi_handle_lock_handle (handle);
+       pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
+                             handle);
+       thr_ret = _wapi_handle_lock_handle (handle);
+       g_assert (thr_ret == 0);
+       
        if(_wapi_handle_issignalled (handle)==FALSE) {
-
 #ifdef DEBUG
                g_message(G_GNUC_PRETTY_FUNCTION
                          ": No need to reset event handle %p", handle);
 #endif
-
-               _wapi_handle_unlock_handle (handle);
-               return(TRUE);
-       }
-       
+       } else {
 #ifdef DEBUG
-       g_message(G_GNUC_PRETTY_FUNCTION
-                 ": Obtained write lock on event handle %p", handle);
+               g_message(G_GNUC_PRETTY_FUNCTION
+                         ": Obtained write lock on event handle %p", handle);
 #endif
 
-       _wapi_handle_set_signal_state (handle, FALSE, FALSE);
-
-       _wapi_handle_unlock_handle (handle);
+               _wapi_handle_set_signal_state (handle, FALSE, FALSE);
+       }
+       
+       event_handle->set_count = 0;
+       
+       thr_ret = _wapi_handle_unlock_handle (handle);
+       g_assert (thr_ret == 0);
+       
+       pthread_cleanup_pop (0);
        
        return(TRUE);
 }
@@ -290,6 +327,7 @@ gboolean SetEvent(gpointer handle)
 {
        struct _WapiHandle_event *event_handle;
        gboolean ok;
+       int thr_ret;
        
        ok=_wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
                                (gpointer *)&event_handle, NULL);
@@ -299,7 +337,10 @@ gboolean SetEvent(gpointer handle)
                return(FALSE);
        }
        
-       _wapi_handle_lock_handle (handle);
+       pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
+                             handle);
+       thr_ret = _wapi_handle_lock_handle (handle);
+       g_assert (thr_ret == 0);
 
 #ifdef DEBUG
        g_message(G_GNUC_PRETTY_FUNCTION ": Setting event handle %p", handle);
@@ -308,10 +349,14 @@ gboolean SetEvent(gpointer handle)
        if(event_handle->manual==TRUE) {
                _wapi_handle_set_signal_state (handle, TRUE, TRUE);
        } else {
+               event_handle->set_count++;
                _wapi_handle_set_signal_state (handle, TRUE, FALSE);
        }
 
-       _wapi_handle_unlock_handle (handle);
+       thr_ret = _wapi_handle_unlock_handle (handle);
+       g_assert (thr_ret == 0);
+       
+       pthread_cleanup_pop (0);
 
        return(TRUE);
 }