server: Make select on all handles a separate operation.

This commit is contained in:
Alexandre Julliard 2013-08-22 10:43:36 +02:00
parent cbdc0ec72d
commit 042e0046d4
5 changed files with 20 additions and 16 deletions

View File

@ -1173,9 +1173,8 @@ NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles,
if (!count || count > MAXIMUM_WAIT_OBJECTS) return STATUS_INVALID_PARAMETER_1;
if (wait_all) flags |= SELECT_ALL;
if (alertable) flags |= SELECT_ALERTABLE;
select_op.wait.op = SELECT_WAIT;
select_op.wait.op = wait_all ? SELECT_WAIT_ALL : SELECT_WAIT;
for (i = 0; i < count; i++) select_op.wait.handles[i] = wine_server_obj_handle( handles[i] );
return NTDLL_wait_for_multiple_objects( &select_op, offsetof( select_op_t, wait.handles[count] ), flags, timeout, 0 );
}

View File

@ -407,7 +407,8 @@ struct token_groups
enum select_op
{
SELECT_NONE,
SELECT_WAIT
SELECT_WAIT,
SELECT_WAIT_ALL
};
typedef union
@ -1082,9 +1083,8 @@ struct select_reply
obj_handle_t apc_handle;
char __pad_60[4];
};
#define SELECT_ALL 1
#define SELECT_ALERTABLE 2
#define SELECT_INTERRUPTIBLE 4
#define SELECT_ALERTABLE 1
#define SELECT_INTERRUPTIBLE 2
@ -5787,6 +5787,6 @@ union generic_reply
struct set_suspend_context_reply set_suspend_context_reply;
};
#define SERVER_PROTOCOL_VERSION 444
#define SERVER_PROTOCOL_VERSION 445
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -423,7 +423,8 @@ struct token_groups
enum select_op
{
SELECT_NONE,
SELECT_WAIT
SELECT_WAIT,
SELECT_WAIT_ALL
};
typedef union
@ -431,7 +432,7 @@ typedef union
enum select_op op;
struct
{
enum select_op op; /* SELECT_WAIT */
enum select_op op; /* SELECT_WAIT or SELECT_WAIT_ALL */
obj_handle_t handles[MAXIMUM_WAIT_OBJECTS];
} wait;
} select_op_t;
@ -946,9 +947,8 @@ struct rawinput_device
apc_call_t call; /* APC call arguments */
obj_handle_t apc_handle; /* handle to next APC */
@END
#define SELECT_ALL 1
#define SELECT_ALERTABLE 2
#define SELECT_INTERRUPTIBLE 4
#define SELECT_ALERTABLE 1
#define SELECT_INTERRUPTIBLE 2
/* Create an event */

View File

@ -75,6 +75,7 @@ struct thread_wait
struct thread *thread; /* owner thread */
int count; /* count of objects */
int flags;
enum select_op select;
client_ptr_t cookie; /* magic cookie to return to client */
timeout_t timeout;
struct timeout_user *user;
@ -558,7 +559,8 @@ static void end_wait( struct thread *thread )
}
/* build the thread wait structure */
static int wait_on( unsigned int count, struct object *objects[], int flags, timeout_t timeout )
static int wait_on( const select_op_t *select_op, unsigned int count, struct object *objects[],
int flags, timeout_t timeout )
{
struct thread_wait *wait;
struct wait_queue_entry *entry;
@ -569,6 +571,7 @@ static int wait_on( unsigned int count, struct object *objects[], int flags, tim
wait->thread = current;
wait->count = count;
wait->flags = flags;
wait->select = select_op->op;
wait->user = NULL;
wait->timeout = timeout;
current->wait = wait;
@ -602,7 +605,7 @@ static int check_wait( struct thread *thread )
/* Suspended threads may not acquire locks, but they can run system APCs */
if (thread->process->suspend + thread->suspend > 0) return -1;
if (wait->flags & SELECT_ALL)
if (wait->select == SELECT_WAIT_ALL)
{
int not_ok = 0;
/* Note: we must check them all anyway, as some objects may
@ -726,6 +729,7 @@ static timeout_t select_on( const select_op_t *select_op, data_size_t op_size, c
break;
case SELECT_WAIT:
case SELECT_WAIT_ALL:
count = (op_size - offsetof( select_op_t, wait.handles )) / sizeof(select_op->wait.handles[0]);
if (op_size < offsetof( select_op_t, wait.handles ) || count > MAXIMUM_WAIT_OBJECTS)
{
@ -747,7 +751,7 @@ static timeout_t select_on( const select_op_t *select_op, data_size_t op_size, c
}
if (i < count) goto done;
if (!wait_on( count, objects, flags, timeout )) goto done;
if (!wait_on( select_op, count, objects, flags, timeout )) goto done;
/* signal the object */
if (signal_obj)

View File

@ -399,7 +399,8 @@ static void dump_varargs_select_op( const char *prefix, data_size_t size )
fprintf( stderr, "NONE" );
break;
case SELECT_WAIT:
fprintf( stderr, "WAIT" );
case SELECT_WAIT_ALL:
fprintf( stderr, "%s", data.op == SELECT_WAIT ? "WAIT" : "WAIT_ALL" );
if (size > offsetof( select_op_t, wait.handles ))
dump_handles( ",handles=", data.wait.handles,
min( size, sizeof(data.wait) ) - offsetof( select_op_t, wait.handles ));