2008-12-08 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mono / io-layer / wait.c
index 228d17dd134694e3095656e7cc9f7e10148b3763..50a8b5038f8eded92d34499e60fadc8d3ecd1388 100644 (file)
@@ -106,6 +106,11 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout,
                        return(WAIT_FAILED);
                }
        }
+
+       if ((GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
+               SetLastError (ERROR_INVALID_HANDLE);
+               return(WAIT_FAILED);
+       }
        
        if (_wapi_handle_test_capabilities (handle,
                                            WAPI_HANDLE_CAP_WAIT) == FALSE) {
@@ -321,6 +326,16 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
                        return(WAIT_FAILED);
                }
        }
+
+       if ((GPOINTER_TO_UINT (signal_handle) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
+               SetLastError (ERROR_INVALID_HANDLE);
+               return(WAIT_FAILED);
+       }
+
+       if ((GPOINTER_TO_UINT (wait) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
+               SetLastError (ERROR_INVALID_HANDLE);
+               return(WAIT_FAILED);
+       }
        
        if (_wapi_handle_test_capabilities (signal_handle,
                                            WAPI_HANDLE_CAP_SIGNAL)==FALSE) {
@@ -546,6 +561,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
        guint32 ret;
        int thr_ret;
        gpointer current_thread = _wapi_thread_handle_from_id (pthread_self ());
+       guint32 retval;
        
        if (current_thread == NULL) {
                SetLastError (ERROR_INVALID_HANDLE);
@@ -581,6 +597,16 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
                                break;
                        }
                }
+
+               if ((GPOINTER_TO_UINT (handles[i]) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
+#ifdef DEBUG
+                       g_message ("%s: Handle %d pseudo process", __func__,
+                                  i);
+#endif
+
+                       bogustype = TRUE;
+                       break;
+               }
                
                exists = g_hash_table_lookup (dups, handles[i]);
                if (exists != NULL) {
@@ -643,6 +669,14 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
                return WAIT_IO_COMPLETION;
        }
        
+       for (i = 0; i < numobjects; i++) {
+               /* Add a reference, as we need to ensure the handle wont
+                * disappear from under us while we're waiting in the loop
+                * (not lock, as we don't want exclusive access here)
+                */
+               _wapi_handle_ref (handles[i]);
+       }
+
        while(1) {
                /* Prod all handles with prewait methods and
                 * special-wait handles that aren't already signalled
@@ -660,7 +694,8 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
                done = test_and_own (numobjects, handles, waitall,
                                     &count, &lowest);
                if (done == TRUE) {
-                       return(WAIT_OBJECT_0 + lowest);
+                       retval = WAIT_OBJECT_0 + lowest;
+                       break;
                }
                
 #ifdef DEBUG
@@ -687,7 +722,8 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
                
                if (alertable && _wapi_thread_apc_pending (current_thread)) {
                        _wapi_thread_dispatch_apc_queue (current_thread);
-                       return WAIT_IO_COMPLETION;
+                       retval = WAIT_IO_COMPLETION;
+                       break;
                }
        
                /* Check if everything is signalled, as we can't
@@ -697,7 +733,8 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
                done = test_and_own (numobjects, handles, waitall,
                                     &count, &lowest);
                if (done == TRUE) {
-                       return(WAIT_OBJECT_0+lowest);
+                       retval = WAIT_OBJECT_0+lowest;
+                       break;
                } else if (ret != 0) {
                        /* Didn't get all handles, and there was a
                         * timeout or other error
@@ -708,12 +745,20 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
 #endif
 
                        if(ret==ETIMEDOUT) {
-                               return(WAIT_TIMEOUT);
+                               retval = WAIT_TIMEOUT;
                        } else {
-                               return(WAIT_FAILED);
+                               retval = WAIT_FAILED;
                        }
+                       break;
                }
        }
+
+       for (i = 0; i < numobjects; i++) {
+               /* Unref everything we reffed above */
+               _wapi_handle_unref (handles[i]);
+       }
+
+       return retval;
 }
 
 guint32 WaitForMultipleObjects(guint32 numobjects, gpointer *handles,
@@ -721,3 +766,25 @@ guint32 WaitForMultipleObjects(guint32 numobjects, gpointer *handles,
 {
        return WaitForMultipleObjectsEx(numobjects, handles, waitall, timeout, FALSE);
 }
+
+/**
+ * WaitForInputIdle:
+ * @handle: a handle to the process to wait for
+ * @timeout: the maximum time in milliseconds to wait for
+ *
+ * This function returns when either @handle process is waiting
+ * for input, or @timeout ms elapses.  If @timeout is zero, the
+ * process state is tested and the function returns immediately.
+ * If @timeout is %INFINITE, the function waits forever.
+ *
+ * Return value: 0 - @handle process is waiting for input.
+ * %WAIT_TIMEOUT - The @timeout interval elapsed and
+ * @handle process is not waiting for input.  %WAIT_FAILED - an error
+ * occurred. 
+ */
+guint32 WaitForInputIdle(gpointer handle, guint32 timeout)
+{
+       /*TODO: Not implemented*/
+       return WAIT_TIMEOUT;
+}
+