diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-07-04 15:08:56 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-07-04 15:08:56 +0000 |
commit | df4a126d65e4690e9301392974fcc9adf7d4c474 (patch) | |
tree | b7e28720d8dcdc42a4c4a0b607e29401d3e6aa62 /signal.c | |
parent | 0f24cdec9ed4a2023b682e7cd5492b1602100b09 (diff) |
Revert r63758 and related commits
The change is unstable on Windows. Please re-commit it when it correctly
supports Windows.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63852 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'signal.c')
-rw-r--r-- | signal.c | 147 |
1 files changed, 34 insertions, 113 deletions
@@ -62,11 +62,12 @@ ruby_atomic_compare_and_swap(rb_atomic_t *ptr, rb_atomic_t cmp, } #endif -#define FOREACH_SIGNAL(sig, offset) \ - for (sig = siglist + (offset); sig < siglist + numberof(siglist); ++sig) -enum { LONGEST_SIGNAME = 7 }; /* MIGRATE and RETRACT */ +#ifndef NSIG +# define NSIG (_SIGMAX + 1) /* For QNX */ +#endif + static const struct signals { - char signm[LONGEST_SIGNAME + 1]; + const char *signm; int signo; } siglist [] = { {"EXIT", 0}, @@ -128,9 +129,15 @@ static const struct signals { #ifdef SIGCONT {"CONT", SIGCONT}, #endif -#if RUBY_SIGCHLD - {"CHLD", RUBY_SIGCHLD }, - {"CLD", RUBY_SIGCHLD }, +#ifdef SIGCHLD + {"CHLD", SIGCHLD}, +#endif +#ifdef SIGCLD + {"CLD", SIGCLD}, +#else +# ifdef SIGCHLD + {"CLD", SIGCHLD}, +# endif #endif #ifdef SIGTTIN {"TTIN", SIGTTIN}, @@ -195,6 +202,7 @@ static const struct signals { #ifdef SIGINFO {"INFO", SIGINFO}, #endif + {NULL, 0} }; static const char signame_prefix[3] = "SIG"; @@ -206,7 +214,7 @@ signm2signo(VALUE *sig_ptr, int negative, int exit, int *prefix_ptr) const struct signals *sigs; VALUE vsig = *sig_ptr; const char *nm; - long len, nmlen; + long len; int prefix = 0; if (RB_SYMBOL_P(vsig)) { @@ -260,12 +268,9 @@ signm2signo(VALUE *sig_ptr, int negative, int exit, int *prefix_ptr) } if (prefix_ptr) *prefix_ptr = prefix; - nmlen = len - prefix; - nm += prefix; - if (nmlen > LONGEST_SIGNAME) goto unsupported; - FOREACH_SIGNAL(sigs, !exit) { - if (memcmp(sigs->signm, nm, nmlen) == 0 && - sigs->signm[nmlen] == '\0') { + for (sigs = siglist + !exit; sigs->signm; sigs++) { + if (memcmp(sigs->signm, nm + prefix, len - prefix) == 0 && + sigs->signm[len - prefix] == '\0') { return negative ? -sigs->signo : sigs->signo; } } @@ -277,10 +282,9 @@ signo2signm(int no) { const struct signals *sigs; - FOREACH_SIGNAL(sigs, 0) { + for (sigs = siglist; sigs->signm; sigs++) if (sigs->signo == no) return sigs->signm; - } return 0; } @@ -698,29 +702,12 @@ signal_enque(int sig) ATOMIC_INC(signal_buff.size); } -static rb_atomic_t sigchld_hit; - -/* Prevent compiler from reordering access */ -#define ACCESS_ONCE(type,x) (*((volatile type *)&(x))) - static RETSIGTYPE sighandler(int sig) { int old_errnum = errno; - /* the VM always needs to handle SIGCHLD for rb_waitpid */ - if (sig == RUBY_SIGCHLD) { - rb_vm_t *vm = GET_VM(); - ATOMIC_EXCHANGE(sigchld_hit, 1); - - /* avoid spurious wakeup in main thread iff nobody uses trap(:CHLD) */ - if (vm && ACCESS_ONCE(VALUE, vm->trap_list.cmd[sig])) { - signal_enque(sig); - } - } - else { - signal_enque(sig); - } + signal_enque(sig); rb_thread_wakeup_timer_thread(); #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL) ruby_signal(sig, sighandler); @@ -755,7 +742,6 @@ rb_enable_interrupt(void) #ifdef HAVE_PTHREAD_SIGMASK sigset_t mask; sigemptyset(&mask); - sigaddset(&mask, RUBY_SIGCHLD); /* timer-thread handles this */ pthread_sigmask(SIG_SETMASK, &mask, NULL); #endif } @@ -1066,17 +1052,6 @@ rb_trap_exit(void) } } -void ruby_waitpid_all(rb_vm_t *); /* process.c */ - -/* only runs in the timer-thread */ -void -ruby_sigchld_handler(rb_vm_t *vm) -{ - if (SIGCHLD_LOSSY || ATOMIC_EXCHANGE(sigchld_hit, 0)) { - ruby_waitpid_all(vm); - } -} - void rb_signal_exec(rb_thread_t *th, int sig) { @@ -1143,9 +1118,6 @@ default_handler(int sig) #ifdef SIGUSR2 case SIGUSR2: #endif -#if RUBY_SIGCHLD - case RUBY_SIGCHLD: -#endif func = sighandler; break; #ifdef SIGBUS @@ -1183,9 +1155,6 @@ trap_handler(VALUE *cmd, int sig) VALUE command; if (NIL_P(*cmd)) { - if (sig == RUBY_SIGCHLD) { - goto sig_dfl; - } func = SIG_IGN; } else { @@ -1206,9 +1175,6 @@ trap_handler(VALUE *cmd, int sig) break; case 14: if (memcmp(cptr, "SYSTEM_DEFAULT", 14) == 0) { - if (sig == RUBY_SIGCHLD) { - goto sig_dfl; - } func = SIG_DFL; *cmd = 0; } @@ -1216,9 +1182,6 @@ trap_handler(VALUE *cmd, int sig) case 7: if (memcmp(cptr, "SIG_IGN", 7) == 0) { sig_ign: - if (sig == RUBY_SIGCHLD) { - goto sig_dfl; - } func = SIG_IGN; *cmd = Qtrue; } @@ -1305,7 +1268,7 @@ trap(int sig, sighandler_t func, VALUE command) break; } - ACCESS_ONCE(VALUE, vm->trap_list.cmd[sig]) = command; + vm->trap_list.cmd[sig] = command; vm->trap_list.safe[sig] = rb_safe_level(); return oldcmd; @@ -1421,7 +1384,7 @@ sig_list(void) VALUE h = rb_hash_new(); const struct signals *sigs; - FOREACH_SIGNAL(sigs, 0) { + for (sigs = siglist; sigs->signm; sigs++) { rb_hash_aset(h, rb_fstring_cstr(sigs->signm), INT2FIX(sigs->signo)); } return h; @@ -1450,18 +1413,20 @@ install_sighandler(int signum, sighandler_t handler) # define install_sighandler(signum, handler) \ INSTALL_SIGHANDLER(install_sighandler(signum, handler), #signum, signum) -#if RUBY_SIGCHLD +#if defined(SIGCLD) || defined(SIGCHLD) static int init_sigchld(int sig) { sighandler_t oldfunc; - sighandler_t func = sighandler; oldfunc = ruby_signal(sig, SIG_DFL); if (oldfunc == SIG_ERR) return -1; - ruby_signal(sig, func); - ACCESS_ONCE(VALUE, GET_VM()->trap_list.cmd[sig]) = 0; - + if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) { + ruby_signal(sig, oldfunc); + } + else { + GET_VM()->trap_list.cmd[sig] = 0; + } return 0; } @@ -1577,55 +1542,11 @@ Init_signal(void) install_sighandler(SIGSYS, sig_do_nothing); #endif -#if RUBY_SIGCHLD - init_sigchld(RUBY_SIGCHLD); +#if defined(SIGCLD) + init_sigchld(SIGCLD); +#elif defined(SIGCHLD) + init_sigchld(SIGCHLD); #endif rb_enable_interrupt(); } - -#if defined(HAVE_GRANTPT) -extern int grantpt(int); -#else -static int -fake_grantfd(int masterfd) -{ - errno = ENOSYS; - return -1; -} -#define grantpt(fd) fake_grantfd(fd) -#endif - -int -rb_grantpt(int masterfd) -{ - if (RUBY_SIGCHLD) { - rb_vm_t *vm = GET_VM(); - int ret, e; - - /* - * Prevent waitpid calls from Ruby by taking waitpid_lock. - * Pedantically, grantpt(3) is undefined if a non-default - * SIGCHLD handler is defined, but preventing conflicting - * waitpid calls ought to be sufficient. - * - * We could install the default sighandler temporarily, but that - * could cause SIGCHLD to be missed by other threads. Blocking - * SIGCHLD won't work here, either, unless we stop and restart - * timer-thread (as only timer-thread sees SIGCHLD), but that - * seems like overkill. - */ - rb_nativethread_lock_lock(&vm->waitpid_lock); - { - ret = grantpt(masterfd); /* may spawn `pt_chown' and wait on it */ - if (ret < 0) e = errno; - } - rb_nativethread_lock_unlock(&vm->waitpid_lock); - - if (ret < 0) errno = e; - return ret; - } - else { - return grantpt(masterfd); - } -} |