Ooops, gen-65 is broken, not test-65.
[mono.git] / mono / io-layer / events.c
index 8bd6556a83c7f1dde4c4781b782b6cbe09f5073b..c99175dd34224c2e8c9cae062487d8fdd5041036 100644 (file)
@@ -85,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);
+               }
        }
 }
 
@@ -115,6 +119,8 @@ gpointer CreateEvent(WapiSecurityAttributes *security G_GNUC_UNUSED, gboolean ma
        struct _WapiHandle_event *event_handle;
        gpointer handle;
        gboolean ok;
+       gpointer ret = NULL;
+       int thr_ret;
        
        mono_once (&event_ops_once, event_ops_init);
 
@@ -125,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);
        }
        
@@ -147,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);
 }
 
 /**
@@ -171,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);
@@ -180,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);
@@ -189,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
@@ -212,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);
@@ -233,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);
@@ -247,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);
 }
@@ -289,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);
@@ -298,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);
@@ -307,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);
 }