new module unix.signals: app-level signal handlers

example:

IN: scratchpad USING: unix.ffi unix.signals ;
Loading resource:basis/unix/signals/signals.factor
IN: scratchpad [ V{ "Me not that kind of orc!" "Me busy, leave me alone!" "Work work" "Zug zug" } pop print flush ] SIGINFO add-signal-handler
IN: scratchpad load: 0.60  cmd: factor 41541 running 0.28u 0.16s
Zug zug
load: 0.71  cmd: factor 41541 running 0.28u 0.16s
Work work
load: 0.71  cmd: factor 41541 running 0.28u 0.16s
Me busy, leave me alone!
load: 0.73  cmd: factor 41541 running 0.28u 0.16s
Me not that kind of orc!
db4
Joe Groff 2011-11-08 10:15:44 -08:00
parent 0c58fd5c26
commit fc7c175c9f
5 changed files with 79 additions and 2 deletions

View File

@ -187,12 +187,23 @@ M: stdin cancel-operation
size-read-fd <fd> init-fd <input-port> >>size
data-read-fd <fd> >>data ;
SYMBOL: dispatch-signal-hook
dispatch-signal-hook [ [ drop ] ] initialize
: signal-pipe-fd ( -- n )
OBJ-SIGNAL-PIPE special-object ; inline
: signal-pipe-loop ( port -- )
'[
int heap-size _ io:stream-read
dup [ int deref dispatch-signal-hook get call( x -- ) ] when*
] loop ;
: start-signal-pipe-thread ( -- )
signal-pipe-fd [ <fd> init-fd <input-port>
'[ [ 4 _ io:stream-read ] loop ] "Signals" spawn drop
signal-pipe-fd [
<fd> init-fd <input-port>
'[ _ signal-pipe-loop ] "Signals" spawn drop
] when* ;
M: unix init-stdio

View File

@ -168,4 +168,7 @@ FUNCTION: int unlink ( c-string path ) ;
FUNCTION: int utimes ( c-string path, timeval[2] times ) ;
FUNCTION: ssize_t write ( int fd, void* buf, size_t nbytes ) ;
FUNCTION: int kill ( pid_t pid, int signal ) ;
FUNCTION: int raise ( int signal ) ;
"librt" "librt.so" cdecl add-library

View File

@ -0,0 +1,34 @@
USING: calendar continuations io kernel math namespaces threads
tools.test unix.ffi unix.signals ;
IN: unix.signals.tests
SYMBOL: sigusr1-count
0 sigusr1-count set-global
CONSTANT: test-sigusr1-handler [ 1 sigusr1-count +@ ]
"=========" print
"NOTE: This test uses SIGUSR1. It may break or cause unwanted behavior" print
"if other SIGUSR1 handlers are installed." print
"=========" print flush
test-sigusr1-handler SIGUSR1 add-signal-handler
[
[ 1 ] [
sigusr1-count get-global
SIGUSR1 raise drop
0.5 seconds sleep
sigusr1-count get-global
swap -
] unit-test
] [ test-sigusr1-handler SIGUSR1 remove-signal-handler ] [ ] cleanup
[ 0 ] [
sigusr1-count get-global
SIGUSR1 raise drop
0.5 seconds sleep
sigusr1-count get-global swap -
] unit-test

View File

@ -0,0 +1,23 @@
! (c)2011 Joe Groff bsd license
USING: assocs io.backend.unix kernel namespaces sequences
threads ;
IN: unix.signals
<PRIVATE
SYMBOL: signal-handlers
signal-handlers [ H{ } ] initialize
PRIVATE>
: dispatch-signal ( sig -- )
signal-handlers get-global at [ in-thread ] each ;
: add-signal-handler ( handler: ( -- ) sig -- )
signal-handlers get-global push-at ;
: remove-signal-handler ( handler sig -- )
signal-handlers get-global at [ remove! drop ] [ drop ] if* ;
[ dispatch-signal ] dispatch-signal-hook set-global

View File

@ -318,6 +318,12 @@ void factor_vm::unix_init_signals()
init_sigaction_with_handler(&enqueue_sigaction, enqueue_signal_handler);
sigaction_safe(SIGWINCH,&enqueue_sigaction,NULL);
sigaction_safe(SIGUSR1,&enqueue_sigaction,NULL);
sigaction_safe(SIGCONT,&enqueue_sigaction,NULL);
sigaction_safe(SIGURG,&enqueue_sigaction,NULL);
sigaction_safe(SIGIO,&enqueue_sigaction,NULL);
sigaction_safe(SIGPROF,&enqueue_sigaction,NULL);
sigaction_safe(SIGVTALRM,&enqueue_sigaction,NULL);
#ifdef SIGINFO
sigaction_safe(SIGINFO,&enqueue_sigaction,NULL);
#endif