mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-06 03:08:19 +00:00
server: Add separate requests for getting/setting the thread context during suspend.
This commit is contained in:
parent
0c69e7f214
commit
45075b2f9c
|
@ -72,10 +72,8 @@ void wait_suspend( CONTEXT *context )
|
|||
context_to_server( &server_context, context );
|
||||
|
||||
/* store the context we got at suspend time */
|
||||
SERVER_START_REQ( set_thread_context )
|
||||
SERVER_START_REQ( set_suspend_context )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( GetCurrentThread() );
|
||||
req->suspend = 1;
|
||||
wine_server_add_data( req, &server_context, sizeof(server_context) );
|
||||
wine_server_call( req );
|
||||
}
|
||||
|
@ -86,10 +84,8 @@ void wait_suspend( CONTEXT *context )
|
|||
NTDLL_wait_for_multiple_objects( 0, NULL, SELECT_INTERRUPTIBLE, &timeout, 0 );
|
||||
|
||||
/* retrieve the new context */
|
||||
SERVER_START_REQ( get_thread_context )
|
||||
SERVER_START_REQ( get_suspend_context )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( GetCurrentThread() );
|
||||
req->suspend = 1;
|
||||
wine_server_set_reply( req, &server_context, sizeof(server_context) );
|
||||
wine_server_call( req );
|
||||
}
|
||||
|
|
|
@ -4815,6 +4815,32 @@ struct set_cursor_reply
|
|||
#define SET_CURSOR_CLIP 0x08
|
||||
|
||||
|
||||
|
||||
struct get_suspend_context_request
|
||||
{
|
||||
struct request_header __header;
|
||||
char __pad_12[4];
|
||||
};
|
||||
struct get_suspend_context_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
/* VARARG(context,context); */
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct set_suspend_context_request
|
||||
{
|
||||
struct request_header __header;
|
||||
/* VARARG(context,context); */
|
||||
char __pad_12[4];
|
||||
};
|
||||
struct set_suspend_context_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
};
|
||||
|
||||
|
||||
enum request
|
||||
{
|
||||
REQ_new_process,
|
||||
|
@ -5060,6 +5086,8 @@ enum request
|
|||
REQ_alloc_user_handle,
|
||||
REQ_free_user_handle,
|
||||
REQ_set_cursor,
|
||||
REQ_get_suspend_context,
|
||||
REQ_set_suspend_context,
|
||||
REQ_NB_REQUESTS
|
||||
};
|
||||
|
||||
|
@ -5310,6 +5338,8 @@ union generic_request
|
|||
struct alloc_user_handle_request alloc_user_handle_request;
|
||||
struct free_user_handle_request free_user_handle_request;
|
||||
struct set_cursor_request set_cursor_request;
|
||||
struct get_suspend_context_request get_suspend_context_request;
|
||||
struct set_suspend_context_request set_suspend_context_request;
|
||||
};
|
||||
union generic_reply
|
||||
{
|
||||
|
@ -5558,8 +5588,10 @@ union generic_reply
|
|||
struct alloc_user_handle_reply alloc_user_handle_reply;
|
||||
struct free_user_handle_reply free_user_handle_reply;
|
||||
struct set_cursor_reply set_cursor_reply;
|
||||
struct get_suspend_context_reply get_suspend_context_reply;
|
||||
struct set_suspend_context_reply set_suspend_context_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 422
|
||||
#define SERVER_PROTOCOL_VERSION 423
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -1863,7 +1863,7 @@ enum char_info_mode
|
|||
@REQ(get_thread_context)
|
||||
obj_handle_t handle; /* thread handle */
|
||||
unsigned int flags; /* context flags */
|
||||
int suspend; /* if getting context during suspend */
|
||||
int suspend; /* suspend the thread if needed */
|
||||
@REPLY
|
||||
int self; /* was it a handle to the current thread? */
|
||||
VARARG(context,context); /* thread context */
|
||||
|
@ -1873,7 +1873,7 @@ enum char_info_mode
|
|||
/* Set the current context of a thread */
|
||||
@REQ(set_thread_context)
|
||||
obj_handle_t handle; /* thread handle */
|
||||
int suspend; /* if setting context during suspend */
|
||||
int suspend; /* suspend the thread if needed */
|
||||
VARARG(context,context); /* thread context */
|
||||
@REPLY
|
||||
int self; /* was it a handle to the current thread? */
|
||||
|
@ -3328,3 +3328,16 @@ enum coords_relative
|
|||
#define SET_CURSOR_COUNT 0x02
|
||||
#define SET_CURSOR_POS 0x04
|
||||
#define SET_CURSOR_CLIP 0x08
|
||||
|
||||
|
||||
/* Retrieve the suspended context of a thread */
|
||||
@REQ(get_suspend_context)
|
||||
@REPLY
|
||||
VARARG(context,context); /* thread context */
|
||||
@END
|
||||
|
||||
|
||||
/* Store the suspend context of a thread */
|
||||
@REQ(set_suspend_context)
|
||||
VARARG(context,context); /* thread context */
|
||||
@END
|
||||
|
|
|
@ -354,6 +354,8 @@ DECL_HANDLER(set_window_layered_info);
|
|||
DECL_HANDLER(alloc_user_handle);
|
||||
DECL_HANDLER(free_user_handle);
|
||||
DECL_HANDLER(set_cursor);
|
||||
DECL_HANDLER(get_suspend_context);
|
||||
DECL_HANDLER(set_suspend_context);
|
||||
|
||||
#ifdef WANT_REQUEST_HANDLERS
|
||||
|
||||
|
@ -603,6 +605,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||
(req_handler)req_alloc_user_handle,
|
||||
(req_handler)req_free_user_handle,
|
||||
(req_handler)req_set_cursor,
|
||||
(req_handler)req_get_suspend_context,
|
||||
(req_handler)req_set_suspend_context,
|
||||
};
|
||||
|
||||
C_ASSERT( sizeof(affinity_t) == 8 );
|
||||
|
@ -2108,6 +2112,9 @@ C_ASSERT( FIELD_OFFSET(struct set_cursor_reply, new_y) == 28 );
|
|||
C_ASSERT( FIELD_OFFSET(struct set_cursor_reply, new_clip) == 32 );
|
||||
C_ASSERT( FIELD_OFFSET(struct set_cursor_reply, last_change) == 48 );
|
||||
C_ASSERT( sizeof(struct set_cursor_reply) == 56 );
|
||||
C_ASSERT( sizeof(struct get_suspend_context_request) == 16 );
|
||||
C_ASSERT( sizeof(struct get_suspend_context_reply) == 8 );
|
||||
C_ASSERT( sizeof(struct set_suspend_context_request) == 16 );
|
||||
|
||||
#endif /* WANT_REQUEST_HANDLERS */
|
||||
|
||||
|
|
|
@ -1472,21 +1472,7 @@ DECL_HANDLER(get_thread_context)
|
|||
}
|
||||
if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return;
|
||||
|
||||
if (req->suspend)
|
||||
{
|
||||
if (thread != current || !thread->suspend_context)
|
||||
{
|
||||
/* not suspended, shouldn't happen */
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (thread->context == thread->suspend_context) thread->context = NULL;
|
||||
set_reply_data_ptr( thread->suspend_context, sizeof(context_t) );
|
||||
thread->suspend_context = NULL;
|
||||
}
|
||||
}
|
||||
else if (thread != current && !thread->context)
|
||||
if (thread != current && !thread->context)
|
||||
{
|
||||
/* thread is not suspended, retry (if it's still running) */
|
||||
if (thread->state != RUNNING) set_error( STATUS_ACCESS_DENIED );
|
||||
|
@ -1518,21 +1504,7 @@ DECL_HANDLER(set_thread_context)
|
|||
}
|
||||
if (!(thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT ))) return;
|
||||
|
||||
if (req->suspend)
|
||||
{
|
||||
if (thread != current || thread->context || context->cpu != thread->process->cpu)
|
||||
{
|
||||
/* nested suspend or exception, shouldn't happen */
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
}
|
||||
else if ((thread->suspend_context = mem_alloc( sizeof(context_t) )))
|
||||
{
|
||||
memcpy( thread->suspend_context, get_req_data(), sizeof(context_t) );
|
||||
thread->context = thread->suspend_context;
|
||||
if (thread->debug_break) break_thread( thread );
|
||||
}
|
||||
}
|
||||
else if (thread != current && !thread->context)
|
||||
if (thread != current && !thread->context)
|
||||
{
|
||||
/* thread is not suspended, retry (if it's still running) */
|
||||
if (thread->state != RUNNING) set_error( STATUS_ACCESS_DENIED );
|
||||
|
@ -1552,6 +1524,48 @@ DECL_HANDLER(set_thread_context)
|
|||
release_object( thread );
|
||||
}
|
||||
|
||||
/* retrieve the suspended context of a thread */
|
||||
DECL_HANDLER(get_suspend_context)
|
||||
{
|
||||
if (get_reply_max_size() < sizeof(context_t))
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
|
||||
if (current->suspend_context)
|
||||
{
|
||||
set_reply_data_ptr( current->suspend_context, sizeof(context_t) );
|
||||
if (current->context == current->suspend_context) current->context = NULL;
|
||||
current->suspend_context = NULL;
|
||||
}
|
||||
else set_error( STATUS_INVALID_PARAMETER ); /* not suspended, shouldn't happen */
|
||||
}
|
||||
|
||||
/* store the suspended context of a thread */
|
||||
DECL_HANDLER(set_suspend_context)
|
||||
{
|
||||
const context_t *context = get_req_data();
|
||||
|
||||
if (get_req_data_size() < sizeof(context_t))
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
|
||||
if (current->context || context->cpu != current->process->cpu)
|
||||
{
|
||||
/* nested suspend or exception, shouldn't happen */
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
}
|
||||
else if ((current->suspend_context = mem_alloc( sizeof(context_t) )))
|
||||
{
|
||||
memcpy( current->suspend_context, get_req_data(), sizeof(context_t) );
|
||||
current->context = current->suspend_context;
|
||||
if (current->debug_break) break_thread( current );
|
||||
}
|
||||
}
|
||||
|
||||
/* fetch a selector entry for a thread */
|
||||
DECL_HANDLER(get_selector_entry)
|
||||
{
|
||||
|
|
|
@ -3862,6 +3862,20 @@ static void dump_set_cursor_reply( const struct set_cursor_reply *req )
|
|||
fprintf( stderr, ", last_change=%08x", req->last_change );
|
||||
}
|
||||
|
||||
static void dump_get_suspend_context_request( const struct get_suspend_context_request *req )
|
||||
{
|
||||
}
|
||||
|
||||
static void dump_get_suspend_context_reply( const struct get_suspend_context_reply *req )
|
||||
{
|
||||
dump_varargs_context( " context=", cur_size );
|
||||
}
|
||||
|
||||
static void dump_set_suspend_context_request( const struct set_suspend_context_request *req )
|
||||
{
|
||||
dump_varargs_context( " context=", cur_size );
|
||||
}
|
||||
|
||||
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||
(dump_func)dump_new_process_request,
|
||||
(dump_func)dump_get_new_process_info_request,
|
||||
|
@ -4106,6 +4120,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_alloc_user_handle_request,
|
||||
(dump_func)dump_free_user_handle_request,
|
||||
(dump_func)dump_set_cursor_request,
|
||||
(dump_func)dump_get_suspend_context_request,
|
||||
(dump_func)dump_set_suspend_context_request,
|
||||
};
|
||||
|
||||
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||
|
@ -4352,6 +4368,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_alloc_user_handle_reply,
|
||||
NULL,
|
||||
(dump_func)dump_set_cursor_reply,
|
||||
(dump_func)dump_get_suspend_context_reply,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||
|
@ -4598,6 +4616,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||
"alloc_user_handle",
|
||||
"free_user_handle",
|
||||
"set_cursor",
|
||||
"get_suspend_context",
|
||||
"set_suspend_context",
|
||||
};
|
||||
|
||||
static const struct
|
||||
|
|
Loading…
Reference in a new issue