aboutsummaryrefslogtreecommitdiffstats
path: root/signal.c
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-07-04 15:08:56 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-07-04 15:08:56 +0000
commitdf4a126d65e4690e9301392974fcc9adf7d4c474 (patch)
treeb7e28720d8dcdc42a4c4a0b607e29401d3e6aa62 /signal.c
parent0f24cdec9ed4a2023b682e7cd5492b1602100b09 (diff)
downloadruby-df4a126d65e4690e9301392974fcc9adf7d4c474.tar.gz
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.c147
1 files changed, 34 insertions, 113 deletions
diff --git a/signal.c b/signal.c
index e9f0708510..c781c38c62 100644
--- a/signal.c
+++ b/signal.c
@@ -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);
- }
-}