NTDLL: implement NtSignalAndWaitForSingleObject

Robert Shearman rob at codeweavers.com
Mon Apr 18 13:20:40 CDT 2005


Mike McCormack wrote:

>
> ChangeLog:
> * implement NtSignalAndWaitForSingleObject


>Index: server/thread.c
>===================================================================
>RCS file: /home/wine/wine/server/thread.c,v
>retrieving revision 1.110
>diff -u -p -r1.110 thread.c
>--- server/thread.c	4 Mar 2005 12:38:36 -0000	1.110
>+++ server/thread.c	18 Apr 2005 16:28:02 -0000
>@@ -577,6 +577,73 @@ void wake_up( struct object *obj, int ma
>     }
> }
> 
>+/* 
>+ * signal_object
>+ *
>+ * Try signaling an event flag, a semaphore or a mutex.
>+ * FIXME: find out which operation to do by checking the type of object
>+ */
>+static void signal_object( obj_handle_t handle )
>+{
>+    /* is it an event flag? */
>+    set_error( STATUS_SUCCESS );
>+    event_operation( handle, SET_EVENT );
>+    if (get_error() != STATUS_OBJECT_TYPE_MISMATCH)
>+        return;
>+
>+    /* is it a semaphore? */
>+    set_error( STATUS_SUCCESS );
>+    release_semaphore( handle, 1, NULL );
>+    if (get_error() != STATUS_OBJECT_TYPE_MISMATCH)
>+        return;
>+
>+    /* is it a mutex? */
>+    set_error( STATUS_SUCCESS );
>+    release_mutex( handle, NULL );
>+    if (get_error() != STATUS_OBJECT_TYPE_MISMATCH)
>+        return;
>+
>+    set_error( STATUS_INVALID_HANDLE );
>+}
>  
>

I think this is a little ugly. I'd prefer to see this code do a switch 
on obj->ops and call the relevant function with the raw object instead 
of a handle.

>+
>+static void signal_and_wait( obj_handle_t hsignal, struct object *wait,
>+                            int flags, const abs_time_t *timeout )
>+{
>+    int r;
>+
>+    if (!wait_on( 1, &wait, flags, timeout ))
>+        return;
>+
>+    /* signal the object */
>+    signal_object( hsignal );
>+    if (get_error())
>+    {
>+        end_wait( current );
>+        return;
>+    }
>+
>+    /* check if we woke ourselves up */
>+    if (!current->wait)
>+        return;
>+
>+    r = check_wait( current );
>+    if (r != -1)
>+    {
>+        end_wait( current );
>+        set_error( r );
>+        return;
>+    }
>+
>+    /* check if we need to wait */
>+    if (!(flags & SELECT_TIMEOUT))
>+        return;
>+
>+    current->wait->user = add_timeout_user( &current->wait->timeout,
>+                                            thread_timeout, current->wait );
>+    if (!current->wait->user)
>+        end_wait( current );
>+}
>+
> /* queue an async procedure call */
> int thread_queue_apc( struct thread *thread, struct object *owner, void *func,
>                       enum apc_type type, int system, void *arg1, void *arg2, void *arg3 )
>  
>

This seems to be pretty similar to select_on. Would it not be possible 
to use that function instead of duplicating that code?

Rob



More information about the wine-devel mailing list