[PATCH 7/9] server: add handler for SIGUSR1 (temporary)

Daniel Santos daniel.santos at pobox.com
Sun Sep 13 17:16:04 CDT 2015


Sever will now handle SIGUSR1 as notifcation that a client process has
released a lock and will walk all threads to see if any are ready to
run. This will be replaced by a proper asynchronous message where the
client will tell the server exactly which object was released.
---
 server/signal.c | 12 ++++++++++++
 server/thread.c | 20 ++++++++++++++++++++
 server/thread.h |  1 +
 3 files changed, 33 insertions(+)

diff --git a/server/signal.c b/server/signal.c
index 5e4fe33..f241604 100644
--- a/server/signal.c
+++ b/server/signal.c
@@ -98,6 +98,7 @@ static struct handler *handler_sigterm;
 static struct handler *handler_sigint;
 static struct handler *handler_sigchld;
 static struct handler *handler_sigio;
+static struct handler *handler_sigusr1;
 
 static int watchdog;
 
@@ -239,6 +240,11 @@ static void do_sigio( int signum, siginfo_t *si, void *x )
 }
 #endif
 
+static void do_sigusr1( int signum )
+{
+    do_signal( handler_sigusr1 );
+}
+
 void start_watchdog(void)
 {
     alarm( 3 );
@@ -277,6 +283,7 @@ void init_signals(void)
     if (!(handler_sigint  = create_handler( sigint_callback ))) goto error;
     if (!(handler_sigchld = create_handler( sigchld_callback ))) goto error;
     if (!(handler_sigio   = create_handler( sigio_callback ))) goto error;
+    if (!(handler_sigusr1 = create_handler( sigusr1_callback ))) goto error;
 
     sigemptyset( &blocked_sigset );
     sigaddset( &blocked_sigset, SIGCHLD );
@@ -289,6 +296,7 @@ void init_signals(void)
 #ifdef SIG_PTHREAD_CANCEL
     sigaddset( &blocked_sigset, SIG_PTHREAD_CANCEL );
 #endif
+    sigaddset( &blocked_sigset, SIGUSR1 );
 
     action.sa_mask = blocked_sigset;
     action.sa_flags = 0;
@@ -318,6 +326,10 @@ void init_signals(void)
     action.sa_flags = SA_SIGINFO;
     sigaction( SIGIO, &action, NULL );
 #endif
+    action.sa_handler = do_sigusr1;
+    action.sa_flags = 0;
+    sigaction( SIGUSR1, &action, NULL );
+
     return;
 
 error:
diff --git a/server/thread.c b/server/thread.c
index bb21b93..77ff161 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -737,6 +737,26 @@ do_satisfied:
     return -1;
 }
 
+/* a less-than-elegant solution to waking up threads after a thread releases a native
+ * lock and sends us SIGUSR1 */
+static int quick_n_dirty_check_wait_threads(struct process *p, void *smart_dummy)
+{
+    struct thread *t;
+
+    LIST_FOR_EACH_ENTRY( t, &p->thread_list, struct thread, proc_entry )
+    {
+        if (t->wait)
+            wake_thread ( t );
+    }
+
+    return 0;
+}
+
+void sigusr1_callback(void)
+{
+    enum_processes(quick_n_dirty_check_wait_threads, NULL);
+}
+
 /* send the wakeup signal to a thread */
 static int send_thread_wakeup( struct thread *thread, client_ptr_t cookie, int signaled )
 {
diff --git a/server/thread.h b/server/thread.h
index 2821991..40f3e2f 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -127,6 +127,7 @@ extern struct thread_snapshot *thread_snap( int *count );
 extern struct token *thread_get_impersonation_token( struct thread *thread );
 extern int set_thread_affinity( struct thread *thread, affinity_t affinity );
 extern int is_cpu_supported( enum cpu_type cpu );
+extern void sigusr1_callback(void);
 
 /* ptrace functions */
 
-- 
2.4.6




More information about the wine-devel mailing list