From fc7c175c9f64b8a7f11ca62ed9dfbd46371d48b5 Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Tue, 8 Nov 2011 10:15:44 -0800 Subject: [PATCH] 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! --- basis/io/backend/unix/unix.factor | 15 +++++++++-- basis/unix/ffi/ffi.factor | 3 +++ basis/unix/signals/signals-tests.factor | 34 +++++++++++++++++++++++++ basis/unix/signals/signals.factor | 23 +++++++++++++++++ vm/os-unix.cpp | 6 +++++ 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 basis/unix/signals/signals-tests.factor create mode 100644 basis/unix/signals/signals.factor diff --git a/basis/io/backend/unix/unix.factor b/basis/io/backend/unix/unix.factor index 37dc40bcca..8c01479574 100755 --- a/basis/io/backend/unix/unix.factor +++ b/basis/io/backend/unix/unix.factor @@ -187,12 +187,23 @@ M: stdin cancel-operation size-read-fd init-fd >>size data-read-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 [ init-fd - '[ [ 4 _ io:stream-read ] loop ] "Signals" spawn drop + signal-pipe-fd [ + init-fd + '[ _ signal-pipe-loop ] "Signals" spawn drop ] when* ; M: unix init-stdio diff --git a/basis/unix/ffi/ffi.factor b/basis/unix/ffi/ffi.factor index 6798bb1307..721efc921b 100644 --- a/basis/unix/ffi/ffi.factor +++ b/basis/unix/ffi/ffi.factor @@ -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 diff --git a/basis/unix/signals/signals-tests.factor b/basis/unix/signals/signals-tests.factor new file mode 100644 index 0000000000..7b57e4994f --- /dev/null +++ b/basis/unix/signals/signals-tests.factor @@ -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 + diff --git a/basis/unix/signals/signals.factor b/basis/unix/signals/signals.factor new file mode 100644 index 0000000000..76e392a32e --- /dev/null +++ b/basis/unix/signals/signals.factor @@ -0,0 +1,23 @@ +! (c)2011 Joe Groff bsd license +USING: assocs io.backend.unix kernel namespaces sequences +threads ; +IN: unix.signals + + + +: 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 diff --git a/vm/os-unix.cpp b/vm/os-unix.cpp index f953751799..d5b4ea90a4 100755 --- a/vm/os-unix.cpp +++ b/vm/os-unix.cpp @@ -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