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@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 */