Commit f92fff66 authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

Implemented NtSignalAndWaitForSingleObject.

parent 684f1110
......@@ -44,7 +44,7 @@ extern void dump_ObjectAttributes (const OBJECT_ATTRIBUTES *ObjectAttributes);
extern void NTDLL_get_server_timeout( abs_time_t *when, const LARGE_INTEGER *timeout );
extern void NTDLL_from_server_timeout( LARGE_INTEGER *timeout, const abs_time_t *when );
extern NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UINT flags,
const LARGE_INTEGER *timeout );
const LARGE_INTEGER *timeout, HANDLE signal_object );
/* init routines */
extern BOOL SIGNAL_Init(void);
......
......@@ -1156,7 +1156,7 @@ static HANDLER_DEF(usr1_handler)
init_handler( HANDLER_CONTEXT );
/* wait with 0 timeout, will only return once the thread is no longer suspended */
timeout.QuadPart = 0;
NTDLL_wait_for_multiple_objects( 0, NULL, 0, &timeout );
NTDLL_wait_for_multiple_objects( 0, NULL, 0, &timeout, 0 );
}
......
......@@ -701,7 +701,7 @@ static void call_apcs( BOOL alertable )
* Implementation of NtWaitForMultipleObjects
*/
NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UINT flags,
const LARGE_INTEGER *timeout )
const LARGE_INTEGER *timeout, HANDLE signal_object )
{
NTSTATUS ret;
int cookie;
......@@ -713,6 +713,7 @@ NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UIN
{
req->flags = flags;
req->cookie = &cookie;
req->signal = signal_object;
NTDLL_get_server_timeout( &req->timeout, timeout );
wine_server_add_data( req, handles, count * sizeof(HANDLE) );
ret = wine_server_call( req );
......@@ -722,6 +723,7 @@ NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UIN
if (ret != STATUS_USER_APC) break;
call_apcs( (flags & SELECT_ALERTABLE) != 0 );
if (flags & SELECT_ALERTABLE) break;
signal_object = 0; /* don't signal it multiple times */
}
/* A test on Windows 2000 shows that Windows always yields during
......@@ -748,7 +750,7 @@ NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles,
if (wait_all) flags |= SELECT_ALL;
if (alertable) flags |= SELECT_ALERTABLE;
return NTDLL_wait_for_multiple_objects( count, handles, flags, timeout );
return NTDLL_wait_for_multiple_objects( count, handles, flags, timeout, 0 );
}
......@@ -762,6 +764,20 @@ NTSTATUS WINAPI NtWaitForSingleObject(HANDLE handle, BOOLEAN alertable, const LA
/******************************************************************
* NtSignalAndWaitForSingleObject (NTDLL.@)
*/
NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE hSignalObject, HANDLE hWaitObject,
BOOLEAN alertable, const LARGE_INTEGER *timeout )
{
UINT flags = SELECT_INTERRUPTIBLE;
if (!hSignalObject) return STATUS_INVALID_HANDLE;
if (alertable) flags |= SELECT_ALERTABLE;
return NTDLL_wait_for_multiple_objects( 1, &hWaitObject, flags, timeout, hSignalObject );
}
/******************************************************************
* NtYieldExecution (NTDLL.@)
*/
NTSTATUS WINAPI NtYieldExecution(void)
......@@ -785,7 +801,7 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou
{
UINT flags = SELECT_INTERRUPTIBLE;
if (alertable) flags |= SELECT_ALERTABLE;
return NTDLL_wait_for_multiple_objects( 0, NULL, flags, timeout );
return NTDLL_wait_for_multiple_objects( 0, NULL, flags, timeout, 0 );
}
if (!timeout) /* sleep forever */
......@@ -819,14 +835,3 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou
}
return STATUS_SUCCESS;
}
/******************************************************************
* NtSignalAndWaitForSingleObject (NTDLL.@)
*/
NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE hSignalObject, HANDLE hWaitObject,
BOOLEAN bAlertable, PLARGE_INTEGER Timeout )
{
FIXME("%p %p %d %p\n", hSignalObject, hWaitObject, bAlertable, Timeout);
return STATUS_SUCCESS;
}
......@@ -603,6 +603,7 @@ struct select_request
struct request_header __header;
int flags;
void* cookie;
obj_handle_t signal;
abs_time_t timeout;
/* VARARG(handles,handles); */
};
......@@ -3902,6 +3903,6 @@ union generic_reply
struct set_mailslot_info_reply set_mailslot_info_reply;
};
#define SERVER_PROTOCOL_VERSION 170
#define SERVER_PROTOCOL_VERSION 171
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
......@@ -1521,7 +1521,7 @@ NTSTATUS WINAPI NtSetSecurityObject(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCR
NTSTATUS WINAPI NtSetSystemTime(const LARGE_INTEGER*,LARGE_INTEGER*);
NTSTATUS WINAPI NtSetTimer(HANDLE, const LARGE_INTEGER*, PTIMERAPCROUTINE, PVOID, BOOLEAN, ULONG, BOOLEAN*);
NTSTATUS WINAPI NtSetValueKey(HKEY,const UNICODE_STRING *,ULONG,ULONG,const void *,ULONG);
NTSTATUS WINAPI NtSignalAndWaitForSingleObject(HANDLE,HANDLE,BOOLEAN,PLARGE_INTEGER);
NTSTATUS WINAPI NtSignalAndWaitForSingleObject(HANDLE,HANDLE,BOOLEAN,const LARGE_INTEGER*);
NTSTATUS WINAPI NtSuspendThread(HANDLE,PULONG);
NTSTATUS WINAPI NtTerminateProcess(HANDLE,LONG);
NTSTATUS WINAPI NtTerminateThread(HANDLE,LONG);
......
......@@ -70,7 +70,8 @@ static const struct object_ops atom_table_ops =
no_add_queue, /* add_queue */
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satified */
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
atom_table_destroy /* destroy */
};
......
......@@ -71,6 +71,7 @@ static const struct object_ops change_ops =
remove_queue, /* remove_queue */
change_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
change_destroy /* destroy */
};
......
......@@ -46,6 +46,7 @@ static const struct object_ops console_input_ops =
NULL, /* remove_queue */
NULL, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
console_input_destroy /* destroy */
};
......@@ -70,6 +71,7 @@ static const struct object_ops console_input_events_ops =
remove_queue, /* remove_queue */
console_input_events_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
console_input_events_destroy /* destroy */
};
......@@ -105,6 +107,7 @@ static const struct object_ops screen_buffer_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
screen_buffer_destroy /* destroy */
};
......
......@@ -72,6 +72,7 @@ static const struct object_ops debug_event_ops =
remove_queue, /* remove_queue */
debug_event_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
debug_event_destroy /* destroy */
};
......@@ -88,6 +89,7 @@ static const struct object_ops debug_ctx_ops =
remove_queue, /* remove_queue */
debug_ctx_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
debug_ctx_destroy /* destroy */
};
......
......@@ -41,6 +41,7 @@ struct event
static void event_dump( struct object *obj, int verbose );
static int event_signaled( struct object *obj, struct thread *thread );
static int event_satisfied( struct object *obj, struct thread *thread );
static int event_signal( struct object *obj, unsigned int access);
static const struct object_ops event_ops =
{
......@@ -50,6 +51,7 @@ static const struct object_ops event_ops =
remove_queue, /* remove_queue */
event_signaled, /* signaled */
event_satisfied, /* satisfied */
event_signal, /* signal */
no_get_fd, /* get_fd */
no_destroy /* destroy */
};
......@@ -123,6 +125,20 @@ static int event_satisfied( struct object *obj, struct thread *thread )
return 0; /* Not abandoned */
}
static int event_signal( struct object *obj, unsigned int access )
{
struct event *event = (struct event *)obj;
assert( obj->ops == &event_ops );
if (!(access & EVENT_MODIFY_STATE))
{
set_error( STATUS_ACCESS_DENIED );
return 0;
}
set_event( event );
return 1;
}
/* create an event */
DECL_HANDLER(create_event)
{
......
......@@ -159,6 +159,7 @@ static const struct object_ops fd_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
fd_destroy /* destroy */
};
......@@ -188,6 +189,7 @@ static const struct object_ops inode_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
inode_destroy /* destroy */
};
......@@ -218,6 +220,7 @@ static const struct object_ops file_lock_ops =
remove_queue, /* remove_queue */
file_lock_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
no_destroy /* destroy */
};
......
......@@ -83,6 +83,7 @@ static const struct object_ops file_ops =
default_fd_remove_queue, /* remove_queue */
default_fd_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
file_get_fd, /* get_fd */
file_destroy /* destroy */
};
......
......@@ -106,6 +106,7 @@ static const struct object_ops handle_table_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
handle_table_destroy /* destroy */
};
......@@ -385,6 +386,16 @@ struct object *get_handle_obj( struct process *process, obj_handle_t handle,
return grab_object( obj );
}
/* retrieve the access rights of a given handle */
unsigned int get_handle_access( struct process *process, obj_handle_t handle )
{
struct handle_entry *entry;
if (get_magic_handle( handle )) return ~0U; /* magic handles have all access rights */
if (!(entry = get_handle( process, handle ))) return 0;
return entry->access;
}
/* retrieve the cached fd for a given handle */
int get_handle_unix_fd( struct process *process, obj_handle_t handle, unsigned int access )
{
......
......@@ -38,6 +38,7 @@ extern obj_handle_t alloc_handle( struct process *process, void *obj,
extern int close_handle( struct process *process, obj_handle_t handle, int *fd );
extern struct object *get_handle_obj( struct process *process, obj_handle_t handle,
unsigned int access, const struct object_ops *ops );
extern unsigned int get_handle_access( struct process *process, obj_handle_t handle );
extern int get_handle_unix_fd( struct process *process, obj_handle_t handle, unsigned int access );
extern int set_handle_info( struct process *process, obj_handle_t handle, int mask, int flags, int *fd );
extern obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, struct process *dst,
......
......@@ -77,6 +77,7 @@ static const struct object_ops hook_table_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
hook_table_destroy /* destroy */
};
......
......@@ -72,6 +72,7 @@ static const struct object_ops mailslot_ops =
default_fd_remove_queue, /* remove_queue */
default_fd_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
mailslot_get_fd, /* get_fd */
mailslot_destroy /* destroy */
};
......@@ -113,6 +114,7 @@ static const struct object_ops mail_writer_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
no_signal, /* signal */
mail_writer_get_fd, /* get_fd */
mail_writer_destroy /* destroy */
};
......
......@@ -62,6 +62,7 @@ static const struct object_ops mapping_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
no_signal, /* signal */
mapping_get_fd, /* get_fd */
mapping_destroy /* destroy */
};
......
......@@ -44,6 +44,7 @@ static void mutex_dump( struct object *obj, int verbose );
static int mutex_signaled( struct object *obj, struct thread *thread );
static int mutex_satisfied( struct object *obj, struct thread *thread );
static void mutex_destroy( struct object *obj );
static int mutex_signal( struct object *obj, unsigned int access );
static const struct object_ops mutex_ops =
{
......@@ -53,6 +54,7 @@ static const struct object_ops mutex_ops =
remove_queue, /* remove_queue */
mutex_signaled, /* signaled */
mutex_satisfied, /* satisfied */
mutex_signal, /* signal */
no_get_fd, /* get_fd */
mutex_destroy /* destroy */
};
......@@ -133,6 +135,25 @@ static int mutex_satisfied( struct object *obj, struct thread *thread )
return 1;
}
static int mutex_signal( struct object *obj, unsigned int access )
{
struct mutex *mutex = (struct mutex *)obj;
assert( obj->ops == &mutex_ops );
if (!(access & SYNCHRONIZE)) /* FIXME: MUTEX_MODIFY_STATE? */
{
set_error( STATUS_ACCESS_DENIED );
return 0;
}
if (!mutex->count || (mutex->owner != current))
{
set_error( STATUS_MUTANT_NOT_OWNED );
return 0;
}
if (!--mutex->count) do_release( mutex );
return 1;
}
static void mutex_destroy( struct object *obj )
{
struct mutex *mutex = (struct mutex *)obj;
......
......@@ -106,6 +106,7 @@ static const struct object_ops named_pipe_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
named_pipe_destroy /* destroy */
};
......@@ -128,6 +129,7 @@ static const struct object_ops pipe_server_ops =
default_fd_remove_queue, /* remove_queue */
default_fd_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
pipe_server_get_fd, /* get_fd */
pipe_server_destroy /* destroy */
};
......@@ -156,6 +158,7 @@ static const struct object_ops pipe_client_ops =
default_fd_remove_queue, /* remove_queue */
default_fd_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
pipe_client_get_fd, /* get_fd */
pipe_client_destroy /* destroy */
};
......
......@@ -273,6 +273,12 @@ int no_satisfied( struct object *obj, struct thread *thread )
return 0; /* not abandoned */
}
int no_signal( struct object *obj, unsigned int access )
{
set_error( STATUS_OBJECT_TYPE_MISMATCH );
return 0;
}
struct fd *no_get_fd( struct object *obj )
{
set_error( STATUS_OBJECT_TYPE_MISMATCH );
......
......@@ -59,6 +59,8 @@ struct object_ops
int (*signaled)(struct object *,struct thread *);
/* wait satisfied; return 1 if abandoned */
int (*satisfied)(struct object *,struct thread *);
/* signal an object */
int (*signal)(struct object *, unsigned int);
/* return an fd object that can be used to read/write from the object */
struct fd *(*get_fd)(struct object *);
/* destroy on refcount == 0 */
......@@ -97,6 +99,7 @@ extern void release_object( void *obj );
extern struct object *find_object( const struct namespace *namespace, const WCHAR *name, size_t len );
extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry );
extern int no_satisfied( struct object *obj, struct thread *thread );
extern int no_signal( struct object *obj, unsigned int access );
extern struct fd *no_get_fd( struct object *obj );
extern void no_destroy( struct object *obj );
#ifdef DEBUG_OBJECTS
......
......@@ -70,6 +70,7 @@ static const struct object_ops process_ops =
remove_queue, /* remove_queue */
process_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
process_destroy /* destroy */
};
......@@ -116,6 +117,7 @@ static const struct object_ops startup_info_ops =
remove_queue, /* remove_queue */
startup_info_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
startup_info_destroy /* destroy */
};
......
......@@ -480,6 +480,7 @@ enum apc_type { APC_NONE, APC_USER, APC_TIMER, APC_ASYNC_IO };
@REQ(select)
int flags; /* wait flags (see below) */
void* cookie; /* magic cookie to return to client */
obj_handle_t signal; /* object to signal (0 if none) */
abs_time_t timeout; /* absolute timeout */
VARARG(handles,handles); /* handles to select on */
@END
......
......@@ -146,6 +146,7 @@ static const struct object_ops msg_queue_ops =
msg_queue_remove_queue, /* remove_queue */
msg_queue_signaled, /* signaled */
msg_queue_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
msg_queue_destroy /* destroy */
};
......@@ -159,6 +160,7 @@ static const struct object_ops thread_input_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
thread_input_destroy /* destroy */
};
......
......@@ -138,6 +138,7 @@ static const struct object_ops key_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
key_destroy /* destroy */
};
......
......@@ -93,6 +93,7 @@ static const struct object_ops master_socket_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
master_socket_destroy /* destroy */
};
......
......@@ -41,6 +41,7 @@ struct semaphore
static void semaphore_dump( struct object *obj, int verbose );
static int semaphore_signaled( struct object *obj, struct thread *thread );
static int semaphore_satisfied( struct object *obj, struct thread *thread );
static int semaphore_signal( struct object *obj, unsigned int access );
static const struct object_ops semaphore_ops =
{
......@@ -50,6 +51,7 @@ static const struct object_ops semaphore_ops =
remove_queue, /* remove_queue */
semaphore_signaled, /* signaled */
semaphore_satisfied, /* satisfied */
semaphore_signal, /* signal */
no_get_fd, /* get_fd */
no_destroy /* destroy */
};
......@@ -77,32 +79,26 @@ static struct semaphore *create_semaphore( const WCHAR *name, size_t len,
return sem;
}
static unsigned int release_semaphore( obj_handle_t handle, unsigned int count )
static int release_semaphore( struct semaphore *sem, unsigned int count,
unsigned int *prev )
{
struct semaphore *sem;
unsigned int prev = 0;
if ((sem = (struct semaphore *)get_handle_obj( current->process, handle,
SEMAPHORE_MODIFY_STATE, &semaphore_ops )))
if (prev) *prev = sem->count;
if (sem->count + count < sem->count || sem->count + count > sem->max)
{
prev = sem->count;
if (sem->count + count < sem->count || sem->count + count > sem->max)
{
set_error( STATUS_SEMAPHORE_LIMIT_EXCEEDED );
}
else if (sem->count)
{
/* there cannot be any thread to wake up if the count is != 0 */
sem->count += count;
}
else
{
sem->count = count;
wake_up( &sem->obj, count );
}
release_object( sem );
set_error( STATUS_SEMAPHORE_LIMIT_EXCEEDED );
return 0;
}
else if (sem->count)
{
/* there cannot be any thread to wake up if the count is != 0 */
sem->count += count;
}
else
{
sem->count = count;
wake_up( &sem->obj, count );
}
return prev;
return 1;
}
static void semaphore_dump( struct object *obj, int verbose )
......@@ -130,6 +126,19 @@ static int semaphore_satisfied( struct object *obj, struct thread *thread )
return 0; /* not abandoned */
}
static int semaphore_signal( struct object *obj, unsigned int access )
{
struct semaphore *sem = (struct semaphore *)obj;
assert( obj->ops == &semaphore_ops );
if (!(access & SEMAPHORE_MODIFY_STATE))
{
set_error( STATUS_ACCESS_DENIED );
return 0;
}
return release_semaphore( sem, 1, NULL );
}
/* create a semaphore */
DECL_HANDLER(create_semaphore)
{
......@@ -154,5 +163,12 @@ DECL_HANDLER(open_semaphore)
/* release a semaphore */
DECL_HANDLER(release_semaphore)
{
reply->prev_count = release_semaphore( req->handle, req->count );
struct semaphore *sem;
if ((sem = (struct semaphore *)get_handle_obj( current->process, req->handle,
SEMAPHORE_MODIFY_STATE, &semaphore_ops )))
{
release_semaphore( sem, req->count, &reply->prev_count );
release_object( sem );
}
}
......@@ -101,6 +101,7 @@ static const struct object_ops serial_ops =
default_fd_remove_queue, /* remove_queue */
default_fd_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
serial_get_fd, /* get_fd */
serial_destroy /* destroy */
};
......
......@@ -62,6 +62,7 @@ static const struct object_ops handler_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
handler_destroy /* destroy */
};
......
......@@ -61,6 +61,7 @@ static const struct object_ops snapshot_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
snapshot_destroy /* destroy */
};
......
......@@ -107,6 +107,7 @@ static const struct object_ops sock_ops =
remove_queue, /* remove_queue */
sock_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
sock_get_fd, /* get_fd */
sock_destroy /* destroy */
};
......
......@@ -92,6 +92,7 @@ static const struct object_ops thread_ops =
remove_queue, /* remove_queue */
thread_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
destroy_thread /* destroy */
};
......@@ -516,9 +517,24 @@ static void thread_timeout( void *ptr )
wake_thread( thread );
}
/* try signaling an event flag, a semaphore or a mutex */
static int signal_object( obj_handle_t handle )
{
struct object *obj;
int ret = 0;
obj = get_handle_obj( current->process, handle, 0, NULL );
if (obj)
{
ret = obj->ops->signal( obj, get_handle_access( current->process, handle ));
release_object( obj );
}
return ret;
}
/* select on a list of handles */
static void select_on( int count, void *cookie, const obj_handle_t *handles,
int flags, const abs_time_t *timeout )
int flags, const abs_time_t *timeout, obj_handle_t signal_obj )
{
int ret, i;
struct object *objects[MAXIMUM_WAIT_OBJECTS];
......@@ -537,6 +553,18 @@ static void select_on( int count, void *cookie, const obj_handle_t *handles,
if (i < count) goto done;
if (!wait_on( count, objects, flags, timeout )) goto done;
/* signal the object */
if (signal_obj)
{
if (!signal_object( signal_obj ))
{
end_wait( current );
goto done;
}
/* check if we woke ourselves up */
if (!current->wait) goto done;
}
if ((ret = check_wait( current )) != -1)
{
/* condition is already satisfied */
......@@ -962,7 +990,7 @@ DECL_HANDLER(resume_thread)
DECL_HANDLER(select)
{
int count = get_req_data_size() / sizeof(int);
select_on( count, req->cookie, get_req_data(), req->flags, &req->timeout );
select_on( count, req->cookie, get_req_data(), req->flags, &req->timeout, req->signal );
}
/* queue an APC for a thread */
......
......@@ -59,6 +59,7 @@ static const struct object_ops timer_ops =
remove_queue, /* remove_queue */
timer_signaled, /* signaled */
timer_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
timer_destroy /* destroy */
};
......
......@@ -79,7 +79,8 @@ static const struct object_ops token_ops =
no_add_queue, /* add_queue */
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satified */
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
token_destroy /* destroy */
};
......
......@@ -760,6 +760,7 @@ static void dump_select_request( const struct select_request *req )
{
fprintf( stderr, " flags=%d,", req->flags );
fprintf( stderr, " cookie=%p,", req->cookie );
fprintf( stderr, " signal=%p,", req->signal );
fprintf( stderr, " timeout=" );
dump_abs_time( &req->timeout );
fprintf( stderr, "," );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment