diff options
author | nagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-02-21 09:33:34 +0000 |
---|---|---|
committer | nagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-02-21 09:33:34 +0000 |
commit | 7e70ac99dee1fc4d5988cc8f3e05480ab6d8fd8c (patch) | |
tree | c51d8eb3ca4cd7f4978b071979fde1cc5723e240 /signal.c | |
parent | cc1e41d9bf82090c9f22c6cebc07a19789d023b4 (diff) | |
download | ruby-7e70ac99dee1fc4d5988cc8f3e05480ab6d8fd8c.tar.gz |
* signal.c: Standard signal handlers ignore signals on non-Ruby native
threads. When a handler is entried with ruby_signal() (like as the
standard signal handlers), the handler for the signal is marked as
it cannot accept non-Ruby native threads. If a handler can treat all
signals on all native threads, please use ruby_nativethread_signal()
to entry it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8007 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'signal.c')
-rw-r--r-- | signal.c | 88 |
1 files changed, 84 insertions, 4 deletions
@@ -303,6 +303,7 @@ static struct { int safe; } trap_list[NSIG]; static rb_atomic_t trap_pending_list[NSIG]; +static char rb_trap_accept_nativethreads[NSIG]; rb_atomic_t rb_trap_pending; rb_atomic_t rb_trap_immediate; int rb_prohibit_interrupt = 1; @@ -334,6 +335,8 @@ ruby_signal(signum, handler) { struct sigaction sigact, old; + rb_trap_accept_nativethreads[signum] = 0; + sigact.sa_handler = handler; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; @@ -360,8 +363,33 @@ posix_signal(signum, handler) { ruby_signal(signum, handler); } -#else -#define ruby_signal(sig,handler) signal((sig),(handler)) + +#ifdef HAVE_NATIVETHREAD +static sighandler_t +ruby_nativethread_signal(signum, handler) + int signum; + sighandler_t handler; +{ + sighandler_t old; + + old = ruby_signal(signum, handler); + rb_trap_accept_nativethreads[signum] = 1; + return old; +} + +void +posix_nativethread_signal(signum, handler) + int signum; + sighandler_t handler; +{ + ruby_nativethread_signal(signum, handler); +} +#endif +#else /* !POSIX_SIGNAL */ +#define ruby_signal(sig,handler) {rb_trap_accept_nativethreads[sig] = 0; signal((sig),(handler));} +#ifdef HAVE_NATIVETHREAD +#define ruby_nativethread_signal(sig,handler) {signal((sig),(handler));rb_trap_accept_nativethreads[sig] = 1;} +#endif #endif static void signal_exec _((int sig)); @@ -408,13 +436,23 @@ sighandler(sig) #else #define IN_MAIN_CONTEXT(f, a) f(a) #endif - if (sig >= NSIG) { rb_bug("trap_handler: Bad signal %d", sig); } +#ifdef HAVE_NATIVETHREAD + if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) { + /* ignore signals on non-Ruby native thread */ + return; + } +#endif + #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL) - ruby_signal(sig, sighandler); + if (rb_trap_accept_nativethreads[sig]) { + ruby_nativethread_signal(sig, sighandler); + } else { + ruby_signal(sig, sighandler); + } #endif if (trap_list[sig].cmd == 0 && ATOMIC_TEST(rb_trap_immediate)) { @@ -433,6 +471,13 @@ static RETSIGTYPE sigbus(sig) int sig; { +#ifdef HAVE_NATIVETHREAD + if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) { + /* ignore signals on non-Ruby native thread */ + return; + } +#endif + rb_bug("Bus Error"); } #endif @@ -443,6 +488,13 @@ static RETSIGTYPE sigsegv(sig) int sig; { +#ifdef HAVE_NATIVETHREAD + if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) { + /* ignore signals on non-Ruby native thread */ + return; + } +#endif + rb_bug("Segmentation fault"); } #endif @@ -508,6 +560,13 @@ static RETSIGTYPE sigexit(sig) int sig; { +#ifdef HAVE_NATIVETHREAD + if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) { + /* ignore signals on non-Ruby native thread */ + return; + } +#endif + rb_exit(0); } @@ -771,6 +830,27 @@ install_sighandler(signum, handler) } } +#ifdef HAVE_NATIVETHREAD +static void +install_nativethread_sighandler(signum, handler) + int signum; + sighandler_t handler; +{ + sighandler_t old; + int old_st; + + old_st = rb_trap_accept_nativethreads[signum]; + old = ruby_nativethread_signal(signum, handler); + if (old != SIG_DFL) { + if (old_st) { + ruby_nativethread_signal(signum, old); + } else { + ruby_signal(signum, old); + } + } +} +#endif + static void init_sigchld(sig) int sig; |