]> gitweb.factorcode.org Git - factor.git/commitdiff
new module unix.signals: app-level signal handlers
authorJoe Groff <arcata@gmail.com>
Tue, 8 Nov 2011 18:15:44 +0000 (10:15 -0800)
committerJoe Groff <arcata@gmail.com>
Tue, 8 Nov 2011 18:21:49 +0000 (10:21 -0800)
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
basis/unix/ffi/ffi.factor
basis/unix/signals/signals-tests.factor [new file with mode: 0644]
basis/unix/signals/signals.factor [new file with mode: 0644]
vm/os-unix.cpp

index 37dc40bcca8bb77ffd84827c64c45394b8554fba..8c01479574fbb6c6c245de6d4367da70fcabbe55 100755 (executable)
@@ -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
index 6798bb1307196148200c9744592363c6a41ef577..721efc921b9b5fb237bafafa64e5e3f7d144ca9c 100644 (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
diff --git a/basis/unix/signals/signals-tests.factor b/basis/unix/signals/signals-tests.factor
new file mode 100644 (file)
index 0000000..7b57e49
--- /dev/null
@@ -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 (file)
index 0000000..76e392a
--- /dev/null
@@ -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
index f95375179952fef943bb44fc550d2a99075ebfab..d5b4ea90a4582ec3fe14d28388b1e4cbbe667f22 100755 (executable)
@@ -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