[PATCH 01/15] server: Wait before suspending threads in APC.
Rémi Bernon
rbernon at codeweavers.com
Mon Jan 27 06:07:04 CST 2020
The APC_BREAK_PROCESS call creates a thread that raises an exception,
suspending the whole process. There's a race condition between this
thread and the APC thread notifying the server of its completion.
This fixes "winedbg --gdb" sometimes not responding after Ctrl-C.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
server/thread.c | 5 +++++
server/thread.h | 1 +
2 files changed, 6 insertions(+)
diff --git a/server/thread.c b/server/thread.c
index 80db41b48d2..a2fd4908792 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -199,6 +199,7 @@ static inline void init_thread_structure( struct thread *thread )
thread->exit_code = 0;
thread->priority = 0;
thread->suspend = 0;
+ thread->in_apc = 0;
thread->desktop_users = 0;
thread->token = NULL;
thread->desc = NULL;
@@ -583,6 +584,7 @@ static void set_thread_info( struct thread *thread,
/* stop a thread (at the Unix level) */
void stop_thread( struct thread *thread )
{
+ if (thread->in_apc) return; /* currently doing apc, will be suspended on return */
if (thread->context) return; /* already inside a debug event, no need for a signal */
/* can't stop a thread while initialisation is in progress */
if (is_process_init_done(thread->process)) send_thread_signal( thread, SIGUSR1 );
@@ -1575,6 +1577,8 @@ DECL_HANDLER(select)
wake_up( &apc->obj, 0 );
close_handle( current->process, req->prev_apc );
release_object( apc );
+ current->in_apc = 0;
+ stop_thread_if_suspended( current );
}
reply->timeout = select_on( &select_op, op_size, req->cookie, req->flags, req->timeout );
@@ -1591,6 +1595,7 @@ DECL_HANDLER(select)
if (apc->call.type != APC_NONE &&
(reply->apc_handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 )))
{
+ current->in_apc = 1;
reply->call = apc->call;
release_object( apc );
break;
diff --git a/server/thread.h b/server/thread.h
index 66e35603d36..08700455972 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -82,6 +82,7 @@ struct thread
affinity_t affinity; /* affinity mask */
int priority; /* priority level */
int suspend; /* suspend count */
+ int in_apc; /* currently doing apc */
obj_handle_t desktop; /* desktop handle */
int desktop_users; /* number of objects using the thread desktop */
timeout_t creation_time; /* Thread creation time */
--
2.25.0
More information about the wine-devel
mailing list