server: Make select on all handles a separate operation.
This commit is contained in:
parent
cbdc0ec72d
commit
042e0046d4
|
@ -1173,9 +1173,8 @@ NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles,
|
||||||
|
|
||||||
if (!count || count > MAXIMUM_WAIT_OBJECTS) return STATUS_INVALID_PARAMETER_1;
|
if (!count || count > MAXIMUM_WAIT_OBJECTS) return STATUS_INVALID_PARAMETER_1;
|
||||||
|
|
||||||
if (wait_all) flags |= SELECT_ALL;
|
|
||||||
if (alertable) flags |= SELECT_ALERTABLE;
|
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] );
|
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 );
|
return NTDLL_wait_for_multiple_objects( &select_op, offsetof( select_op_t, wait.handles[count] ), flags, timeout, 0 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -407,7 +407,8 @@ struct token_groups
|
||||||
enum select_op
|
enum select_op
|
||||||
{
|
{
|
||||||
SELECT_NONE,
|
SELECT_NONE,
|
||||||
SELECT_WAIT
|
SELECT_WAIT,
|
||||||
|
SELECT_WAIT_ALL
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
|
@ -1082,9 +1083,8 @@ struct select_reply
|
||||||
obj_handle_t apc_handle;
|
obj_handle_t apc_handle;
|
||||||
char __pad_60[4];
|
char __pad_60[4];
|
||||||
};
|
};
|
||||||
#define SELECT_ALL 1
|
#define SELECT_ALERTABLE 1
|
||||||
#define SELECT_ALERTABLE 2
|
#define SELECT_INTERRUPTIBLE 2
|
||||||
#define SELECT_INTERRUPTIBLE 4
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -5787,6 +5787,6 @@ union generic_reply
|
||||||
struct set_suspend_context_reply set_suspend_context_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 */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -423,7 +423,8 @@ struct token_groups
|
||||||
enum select_op
|
enum select_op
|
||||||
{
|
{
|
||||||
SELECT_NONE,
|
SELECT_NONE,
|
||||||
SELECT_WAIT
|
SELECT_WAIT,
|
||||||
|
SELECT_WAIT_ALL
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
|
@ -431,7 +432,7 @@ typedef union
|
||||||
enum select_op op;
|
enum select_op op;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
enum select_op op; /* SELECT_WAIT */
|
enum select_op op; /* SELECT_WAIT or SELECT_WAIT_ALL */
|
||||||
obj_handle_t handles[MAXIMUM_WAIT_OBJECTS];
|
obj_handle_t handles[MAXIMUM_WAIT_OBJECTS];
|
||||||
} wait;
|
} wait;
|
||||||
} select_op_t;
|
} select_op_t;
|
||||||
|
@ -946,9 +947,8 @@ struct rawinput_device
|
||||||
apc_call_t call; /* APC call arguments */
|
apc_call_t call; /* APC call arguments */
|
||||||
obj_handle_t apc_handle; /* handle to next APC */
|
obj_handle_t apc_handle; /* handle to next APC */
|
||||||
@END
|
@END
|
||||||
#define SELECT_ALL 1
|
#define SELECT_ALERTABLE 1
|
||||||
#define SELECT_ALERTABLE 2
|
#define SELECT_INTERRUPTIBLE 2
|
||||||
#define SELECT_INTERRUPTIBLE 4
|
|
||||||
|
|
||||||
|
|
||||||
/* Create an event */
|
/* Create an event */
|
||||||
|
|
|
@ -75,6 +75,7 @@ struct thread_wait
|
||||||
struct thread *thread; /* owner thread */
|
struct thread *thread; /* owner thread */
|
||||||
int count; /* count of objects */
|
int count; /* count of objects */
|
||||||
int flags;
|
int flags;
|
||||||
|
enum select_op select;
|
||||||
client_ptr_t cookie; /* magic cookie to return to client */
|
client_ptr_t cookie; /* magic cookie to return to client */
|
||||||
timeout_t timeout;
|
timeout_t timeout;
|
||||||
struct timeout_user *user;
|
struct timeout_user *user;
|
||||||
|
@ -558,7 +559,8 @@ static void end_wait( struct thread *thread )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build the thread wait structure */
|
/* 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 thread_wait *wait;
|
||||||
struct wait_queue_entry *entry;
|
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->thread = current;
|
||||||
wait->count = count;
|
wait->count = count;
|
||||||
wait->flags = flags;
|
wait->flags = flags;
|
||||||
|
wait->select = select_op->op;
|
||||||
wait->user = NULL;
|
wait->user = NULL;
|
||||||
wait->timeout = timeout;
|
wait->timeout = timeout;
|
||||||
current->wait = wait;
|
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 */
|
/* Suspended threads may not acquire locks, but they can run system APCs */
|
||||||
if (thread->process->suspend + thread->suspend > 0) return -1;
|
if (thread->process->suspend + thread->suspend > 0) return -1;
|
||||||
|
|
||||||
if (wait->flags & SELECT_ALL)
|
if (wait->select == SELECT_WAIT_ALL)
|
||||||
{
|
{
|
||||||
int not_ok = 0;
|
int not_ok = 0;
|
||||||
/* Note: we must check them all anyway, as some objects may
|
/* 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;
|
break;
|
||||||
|
|
||||||
case SELECT_WAIT:
|
case SELECT_WAIT:
|
||||||
|
case SELECT_WAIT_ALL:
|
||||||
count = (op_size - offsetof( select_op_t, wait.handles )) / sizeof(select_op->wait.handles[0]);
|
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)
|
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 (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 */
|
/* signal the object */
|
||||||
if (signal_obj)
|
if (signal_obj)
|
||||||
|
|
|
@ -399,7 +399,8 @@ static void dump_varargs_select_op( const char *prefix, data_size_t size )
|
||||||
fprintf( stderr, "NONE" );
|
fprintf( stderr, "NONE" );
|
||||||
break;
|
break;
|
||||||
case SELECT_WAIT:
|
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 ))
|
if (size > offsetof( select_op_t, wait.handles ))
|
||||||
dump_handles( ",handles=", data.wait.handles,
|
dump_handles( ",handles=", data.wait.handles,
|
||||||
min( size, sizeof(data.wait) ) - offsetof( select_op_t, wait.handles ));
|
min( size, sizeof(data.wait) ) - offsetof( select_op_t, wait.handles ));
|
||||||
|
|
Loading…
Reference in New Issue