Commit f3cb4f7d authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Avoid inter-process APCs when called for the process itself.

parent 9d09e699
...@@ -714,6 +714,7 @@ struct queue_apc_reply ...@@ -714,6 +714,7 @@ struct queue_apc_reply
{ {
struct reply_header __header; struct reply_header __header;
obj_handle_t handle; obj_handle_t handle;
int self;
}; };
...@@ -4624,6 +4625,6 @@ union generic_reply ...@@ -4624,6 +4625,6 @@ union generic_reply
struct query_symlink_reply query_symlink_reply; struct query_symlink_reply query_symlink_reply;
}; };
#define SERVER_PROTOCOL_VERSION 273 #define SERVER_PROTOCOL_VERSION 274
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -635,6 +635,7 @@ typedef union ...@@ -635,6 +635,7 @@ typedef union
apc_call_t call; /* call arguments */ apc_call_t call; /* call arguments */
@REPLY @REPLY
obj_handle_t handle; /* APC handle */ obj_handle_t handle; /* APC handle */
int self; /* run APC in caller itself? */
@END @END
......
...@@ -1172,7 +1172,7 @@ DECL_HANDLER(queue_apc) ...@@ -1172,7 +1172,7 @@ DECL_HANDLER(queue_apc)
break; break;
case APC_MAP_VIEW: case APC_MAP_VIEW:
process = get_process_from_handle( req->process, PROCESS_VM_OPERATION ); process = get_process_from_handle( req->process, PROCESS_VM_OPERATION );
if (process) if (process && process != current->process)
{ {
/* duplicate the handle into the target process */ /* duplicate the handle into the target process */
obj_handle_t handle = duplicate_handle( current->process, apc->call.map_view.handle, obj_handle_t handle = duplicate_handle( current->process, apc->call.map_view.handle,
...@@ -1200,18 +1200,22 @@ DECL_HANDLER(queue_apc) ...@@ -1200,18 +1200,22 @@ DECL_HANDLER(queue_apc)
} }
else if (process) else if (process)
{ {
obj_handle_t handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 ); reply->self = (process == current->process);
if (handle) if (!reply->self)
{ {
if (queue_apc( process, NULL, apc )) obj_handle_t handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 );
if (handle)
{ {
apc->caller = (struct thread *)grab_object( current ); if (queue_apc( process, NULL, apc ))
reply->handle = handle; {
} apc->caller = (struct thread *)grab_object( current );
else reply->handle = handle;
{ }
close_handle( current->process, handle ); else
set_error( STATUS_PROCESS_IS_TERMINATING ); {
close_handle( current->process, handle );
set_error( STATUS_PROCESS_IS_TERMINATING );
}
} }
} }
release_object( process ); release_object( process );
......
...@@ -995,7 +995,8 @@ static void dump_queue_apc_request( const struct queue_apc_request *req ) ...@@ -995,7 +995,8 @@ static void dump_queue_apc_request( const struct queue_apc_request *req )
static void dump_queue_apc_reply( const struct queue_apc_reply *req ) static void dump_queue_apc_reply( const struct queue_apc_reply *req )
{ {
fprintf( stderr, " handle=%p", req->handle ); fprintf( stderr, " handle=%p,", req->handle );
fprintf( stderr, " self=%d", req->self );
} }
static void dump_get_apc_request( const struct get_apc_request *req ) static void dump_get_apc_request( const struct get_apc_request *req )
......
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