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( ¤t->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