Dmitry Timoshkov : server: Make it possible to deliver an APC to any thread alive in the process.

Alexandre Julliard julliard at winehq.org
Mon Nov 13 16:24:19 CST 2017


Module: wine
Branch: master
Commit: 288814a4d84d139f37a486964f2a599664e37618
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=288814a4d84d139f37a486964f2a599664e37618

Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date:   Tue Nov  7 11:10:02 2017 +0800

server: Make it possible to deliver an APC to any thread alive in the process.

Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 server/async.c  | 4 ++--
 server/thread.c | 7 +++++--
 server/thread.h | 2 +-
 server/timer.c  | 2 +-
 4 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/server/async.c b/server/async.c
index cf7a434..4e89e1e 100644
--- a/server/async.c
+++ b/server/async.c
@@ -167,7 +167,7 @@ void async_terminate( struct async *async, unsigned int status )
             data.async_io.user   = async->data.user;
             data.async_io.sb     = async->data.iosb;
             data.async_io.status = status;
-            thread_queue_apc( async->thread, &async->obj, &data );
+            thread_queue_apc( NULL, async->thread, &async->obj, &data );
         }
         else async_set_result( &async->obj, STATUS_SUCCESS, 0 );
     }
@@ -373,7 +373,7 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota
             data.user.args[0] = async->data.apc_context;
             data.user.args[1] = async->data.iosb;
             data.user.args[2] = 0;
-            thread_queue_apc( async->thread, NULL, &data );
+            thread_queue_apc( NULL, async->thread, NULL, &data );
         }
         else if (async->data.apc_context)
             add_async_completion( async, async->data.apc_context, status, total );
diff --git a/server/thread.c b/server/thread.c
index 2c864a6..858b450 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -926,6 +926,9 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr
 {
     struct list *queue;
 
+    if (thread && thread->state == TERMINATED && process)
+        thread = NULL;
+
     if (!thread)  /* find a suitable thread inside the process */
     {
         struct thread *candidate;
@@ -977,14 +980,14 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr
 }
 
 /* queue an async procedure call */
-int thread_queue_apc( struct thread *thread, struct object *owner, const apc_call_t *call_data )
+int thread_queue_apc( struct process *process, struct thread *thread, struct object *owner, const apc_call_t *call_data )
 {
     struct thread_apc *apc;
     int ret = 0;
 
     if ((apc = create_apc( owner, call_data )))
     {
-        ret = queue_apc( NULL, thread, apc );
+        ret = queue_apc( process, thread, apc );
         release_object( apc );
     }
     return ret;
diff --git a/server/thread.h b/server/thread.h
index 1d81d61..09d8260 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -120,7 +120,7 @@ extern void remove_queue( struct object *obj, struct wait_queue_entry *entry );
 extern void kill_thread( struct thread *thread, int violent_death );
 extern void break_thread( struct thread *thread );
 extern void wake_up( struct object *obj, int max );
-extern int thread_queue_apc( struct thread *thread, struct object *owner, const apc_call_t *call_data );
+extern int thread_queue_apc( struct process *process, struct thread *thread, struct object *owner, const apc_call_t *call_data );
 extern void thread_cancel_apc( struct thread *thread, struct object *owner, enum apc_type type );
 extern int thread_add_inflight_fd( struct thread *thread, int client, int server );
 extern int thread_get_inflight_fd( struct thread *thread, int client );
diff --git a/server/timer.c b/server/timer.c
index c8b4fa8..3a786fb 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -122,7 +122,7 @@ static void timer_callback( void *private )
         }
         else data.type = APC_NONE;  /* wake up only */
 
-        if (!thread_queue_apc( timer->thread, &timer->obj, &data ))
+        if (!thread_queue_apc( NULL, timer->thread, &timer->obj, &data ))
         {
             release_object( timer->thread );
             timer->thread = NULL;




More information about the wine-cvs mailing list