mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 09:35:52 +00:00
server: Send the APC call data as vararg in the select request.
This commit is contained in:
parent
e3049f11fa
commit
6b5561b601
|
@ -691,10 +691,15 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
|
||||||
int cookie;
|
int cookie;
|
||||||
obj_handle_t apc_handle = 0;
|
obj_handle_t apc_handle = 0;
|
||||||
BOOL suspend_context = !!context;
|
BOOL suspend_context = !!context;
|
||||||
apc_call_t call;
|
|
||||||
apc_result_t result;
|
apc_result_t result;
|
||||||
sigset_t old_set;
|
sigset_t old_set;
|
||||||
int signaled;
|
int signaled;
|
||||||
|
data_size_t reply_size;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
apc_call_t call;
|
||||||
|
context_t context[2];
|
||||||
|
} reply_data;
|
||||||
|
|
||||||
memset( &result, 0, sizeof(result) );
|
memset( &result, 0, sizeof(result) );
|
||||||
|
|
||||||
|
@ -718,16 +723,17 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
|
||||||
wine_server_add_data( req, context, ctx_size );
|
wine_server_add_data( req, context, ctx_size );
|
||||||
suspend_context = FALSE; /* server owns the context now */
|
suspend_context = FALSE; /* server owns the context now */
|
||||||
}
|
}
|
||||||
if (context) wine_server_set_reply( req, context, 2 * sizeof(*context) );
|
wine_server_set_reply( req, &reply_data,
|
||||||
|
context ? sizeof(reply_data) : sizeof(reply_data.call) );
|
||||||
ret = server_call_unlocked( req );
|
ret = server_call_unlocked( req );
|
||||||
signaled = reply->signaled;
|
signaled = reply->signaled;
|
||||||
apc_handle = reply->apc_handle;
|
apc_handle = reply->apc_handle;
|
||||||
call = reply->call;
|
reply_size = wine_server_reply_size( reply );
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
if (ret != STATUS_KERNEL_APC) break;
|
if (ret != STATUS_KERNEL_APC) break;
|
||||||
invoke_system_apc( &call, &result, FALSE );
|
invoke_system_apc( &reply_data.call, &result, FALSE );
|
||||||
|
|
||||||
/* don't signal multiple times */
|
/* don't signal multiple times */
|
||||||
if (size >= sizeof(select_op->signal_and_wait) && select_op->op == SELECT_SIGNAL_AND_WAIT)
|
if (size >= sizeof(select_op->signal_and_wait) && select_op->op == SELECT_SIGNAL_AND_WAIT)
|
||||||
|
@ -740,7 +746,9 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
|
||||||
}
|
}
|
||||||
while (ret == STATUS_USER_APC || ret == STATUS_KERNEL_APC);
|
while (ret == STATUS_USER_APC || ret == STATUS_KERNEL_APC);
|
||||||
|
|
||||||
if (ret == STATUS_USER_APC) *user_apc = call.user;
|
if (ret == STATUS_USER_APC) *user_apc = reply_data.call.user;
|
||||||
|
if (reply_size > sizeof(reply_data.call))
|
||||||
|
memcpy( context, reply_data.context, reply_size - sizeof(reply_data.call) );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1381,9 +1381,9 @@ struct select_request
|
||||||
struct select_reply
|
struct select_reply
|
||||||
{
|
{
|
||||||
struct reply_header __header;
|
struct reply_header __header;
|
||||||
apc_call_t call;
|
|
||||||
obj_handle_t apc_handle;
|
obj_handle_t apc_handle;
|
||||||
int signaled;
|
int signaled;
|
||||||
|
/* VARARG(call,apc_call); */
|
||||||
/* VARARG(contexts,contexts); */
|
/* VARARG(contexts,contexts); */
|
||||||
};
|
};
|
||||||
#define SELECT_ALERTABLE 1
|
#define SELECT_ALERTABLE 1
|
||||||
|
@ -6413,7 +6413,7 @@ union generic_reply
|
||||||
|
|
||||||
/* ### protocol_version begin ### */
|
/* ### protocol_version begin ### */
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 773
|
#define SERVER_PROTOCOL_VERSION 774
|
||||||
|
|
||||||
/* ### protocol_version end ### */
|
/* ### protocol_version end ### */
|
||||||
|
|
||||||
|
|
|
@ -1221,9 +1221,9 @@ typedef struct
|
||||||
VARARG(data,select_op,size); /* operation-specific data */
|
VARARG(data,select_op,size); /* operation-specific data */
|
||||||
VARARG(contexts,contexts); /* suspend context(s) */
|
VARARG(contexts,contexts); /* suspend context(s) */
|
||||||
@REPLY
|
@REPLY
|
||||||
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 */
|
||||||
int signaled; /* were the handles immediately signaled? */
|
int signaled; /* were the handles immediately signaled? */
|
||||||
|
VARARG(call,apc_call); /* APC call arguments */
|
||||||
VARARG(contexts,contexts); /* suspend context(s) */
|
VARARG(contexts,contexts); /* suspend context(s) */
|
||||||
@END
|
@END
|
||||||
#define SELECT_ALERTABLE 1
|
#define SELECT_ALERTABLE 1
|
||||||
|
|
|
@ -689,7 +689,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
||||||
|
|
||||||
C_ASSERT( sizeof(abstime_t) == 8 );
|
C_ASSERT( sizeof(abstime_t) == 8 );
|
||||||
C_ASSERT( sizeof(affinity_t) == 8 );
|
C_ASSERT( sizeof(affinity_t) == 8 );
|
||||||
C_ASSERT( sizeof(apc_call_t) == 48 );
|
|
||||||
C_ASSERT( sizeof(apc_param_t) == 8 );
|
C_ASSERT( sizeof(apc_param_t) == 8 );
|
||||||
C_ASSERT( sizeof(apc_result_t) == 40 );
|
C_ASSERT( sizeof(apc_result_t) == 40 );
|
||||||
C_ASSERT( sizeof(async_data_t) == 40 );
|
C_ASSERT( sizeof(async_data_t) == 40 );
|
||||||
|
@ -909,10 +908,9 @@ C_ASSERT( FIELD_OFFSET(struct select_request, timeout) == 24 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct select_request, size) == 32 );
|
C_ASSERT( FIELD_OFFSET(struct select_request, size) == 32 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct select_request, prev_apc) == 36 );
|
C_ASSERT( FIELD_OFFSET(struct select_request, prev_apc) == 36 );
|
||||||
C_ASSERT( sizeof(struct select_request) == 40 );
|
C_ASSERT( sizeof(struct select_request) == 40 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct select_reply, call) == 8 );
|
C_ASSERT( FIELD_OFFSET(struct select_reply, apc_handle) == 8 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct select_reply, apc_handle) == 56 );
|
C_ASSERT( FIELD_OFFSET(struct select_reply, signaled) == 12 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct select_reply, signaled) == 60 );
|
C_ASSERT( sizeof(struct select_reply) == 16 );
|
||||||
C_ASSERT( sizeof(struct select_reply) == 64 );
|
|
||||||
C_ASSERT( FIELD_OFFSET(struct create_event_request, access) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct create_event_request, access) == 12 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct create_event_request, manual_reset) == 16 );
|
C_ASSERT( FIELD_OFFSET(struct create_event_request, manual_reset) == 16 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct create_event_request, initial_state) == 20 );
|
C_ASSERT( FIELD_OFFSET(struct create_event_request, initial_state) == 20 );
|
||||||
|
|
|
@ -1658,17 +1658,19 @@ DECL_HANDLER(select)
|
||||||
|
|
||||||
reply->signaled = select_on( &select_op, op_size, req->cookie, req->flags, req->timeout );
|
reply->signaled = select_on( &select_op, op_size, req->cookie, req->flags, req->timeout );
|
||||||
|
|
||||||
if (get_error() == STATUS_USER_APC)
|
if (get_error() == STATUS_USER_APC && get_reply_max_size() >= sizeof(apc_call_t))
|
||||||
{
|
{
|
||||||
apc = thread_dequeue_apc( current, 0 );
|
apc = thread_dequeue_apc( current, 0 );
|
||||||
reply->call = apc->call;
|
set_reply_data( &apc->call, sizeof(apc->call) );
|
||||||
release_object( apc );
|
release_object( apc );
|
||||||
}
|
}
|
||||||
else if (get_error() == STATUS_KERNEL_APC)
|
else if (get_error() == STATUS_KERNEL_APC && get_reply_max_size() >= sizeof(apc_call_t))
|
||||||
{
|
{
|
||||||
apc = thread_dequeue_apc( current, 1 );
|
apc = thread_dequeue_apc( current, 1 );
|
||||||
if ((reply->apc_handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 )))
|
if ((reply->apc_handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 )))
|
||||||
reply->call = apc->call;
|
{
|
||||||
|
set_reply_data( &apc->call, sizeof(apc->call) );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
apc->executed = 1;
|
apc->executed = 1;
|
||||||
|
@ -1676,16 +1678,23 @@ DECL_HANDLER(select)
|
||||||
}
|
}
|
||||||
release_object( apc );
|
release_object( apc );
|
||||||
}
|
}
|
||||||
else if (reply->signaled && get_reply_max_size() >= sizeof(context_t) &&
|
else if (reply->signaled && get_reply_max_size() >= sizeof(apc_call_t) + sizeof(context_t) &&
|
||||||
current->context && current->suspend_cookie == req->cookie)
|
current->context && current->suspend_cookie == req->cookie)
|
||||||
{
|
{
|
||||||
ctx = current->context;
|
ctx = current->context;
|
||||||
if (ctx->regs[CTX_NATIVE].flags || ctx->regs[CTX_WOW].flags)
|
if (ctx->regs[CTX_NATIVE].flags || ctx->regs[CTX_WOW].flags)
|
||||||
{
|
{
|
||||||
data_size_t size = (ctx->regs[CTX_WOW].flags ? 2 : 1) * sizeof(context_t);
|
apc_call_t *data;
|
||||||
|
data_size_t size = sizeof(*data) + (ctx->regs[CTX_WOW].flags ? 2 : 1) * sizeof(context_t);
|
||||||
unsigned int flags = system_flags & ctx->regs[CTX_NATIVE].flags;
|
unsigned int flags = system_flags & ctx->regs[CTX_NATIVE].flags;
|
||||||
|
|
||||||
if (flags) set_thread_context( current, &ctx->regs[CTX_NATIVE], flags );
|
if (flags) set_thread_context( current, &ctx->regs[CTX_NATIVE], flags );
|
||||||
set_reply_data( ctx->regs, min( size, get_reply_max_size() ));
|
size = min( size, get_reply_max_size() );
|
||||||
|
if ((data = set_reply_data_size( size )))
|
||||||
|
{
|
||||||
|
memset( data, 0, sizeof(*data) );
|
||||||
|
memcpy( data + 1, ctx->regs, size - sizeof(*data) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
release_object( ctx );
|
release_object( ctx );
|
||||||
current->context = NULL;
|
current->context = NULL;
|
||||||
|
|
|
@ -1752,9 +1752,9 @@ static void dump_select_request( const struct select_request *req )
|
||||||
|
|
||||||
static void dump_select_reply( const struct select_reply *req )
|
static void dump_select_reply( const struct select_reply *req )
|
||||||
{
|
{
|
||||||
dump_apc_call( " call=", &req->call );
|
fprintf( stderr, " apc_handle=%04x", req->apc_handle );
|
||||||
fprintf( stderr, ", apc_handle=%04x", req->apc_handle );
|
|
||||||
fprintf( stderr, ", signaled=%d", req->signaled );
|
fprintf( stderr, ", signaled=%d", req->signaled );
|
||||||
|
dump_varargs_apc_call( ", call=", cur_size );
|
||||||
dump_varargs_contexts( ", contexts=", cur_size );
|
dump_varargs_contexts( ", contexts=", cur_size );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ my %formats =
|
||||||
"timeout_t" => [ 8, 8, "&dump_timeout" ],
|
"timeout_t" => [ 8, 8, "&dump_timeout" ],
|
||||||
"abstime_t" => [ 8, 8, "&dump_abstime" ],
|
"abstime_t" => [ 8, 8, "&dump_abstime" ],
|
||||||
"rectangle_t" => [ 16, 4, "&dump_rectangle" ],
|
"rectangle_t" => [ 16, 4, "&dump_rectangle" ],
|
||||||
"apc_call_t" => [ 48, 8, "&dump_apc_call" ],
|
|
||||||
"apc_result_t" => [ 40, 8, "&dump_apc_result" ],
|
"apc_result_t" => [ 40, 8, "&dump_apc_result" ],
|
||||||
"async_data_t" => [ 40, 8, "&dump_async_data" ],
|
"async_data_t" => [ 40, 8, "&dump_async_data" ],
|
||||||
"irp_params_t" => [ 32, 8, "&dump_irp_params" ],
|
"irp_params_t" => [ 32, 8, "&dump_irp_params" ],
|
||||||
|
|
Loading…
Reference in a new issue