[PATCH 7/8] server: add handler for SIGUSR1 (temporary)
Daniel Santos
daniel.santos at pobox.com
Thu Sep 10 01:34:46 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.
Signed-off-by: Daniel Santos <daniel.santos at pobox.com>
---
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 4ed39d6..b4edfd9 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -721,6 +721,26 @@ static int check_wait( struct thread *thread )
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