[macruby-changes] [3338] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Tue Jan 26 06:18:51 PST 2010
Revision: 3338
http://trac.macosforge.org/projects/ruby/changeset/3338
Author: martinlagardette at apple.com
Date: 2010-01-26 06:18:47 -0800 (Tue, 26 Jan 2010)
Log Message:
-----------
- Some beginning to signal handling. It is not yet complete, as we can't raise withing signal handlers yet
Modified Paths:
--------------
MacRuby/trunk/include/ruby/intern.h
MacRuby/trunk/include/ruby/signal.h
MacRuby/trunk/signal.c
MacRuby/trunk/vm.cpp
MacRuby/trunk/vm.h
Modified: MacRuby/trunk/include/ruby/intern.h
===================================================================
--- MacRuby/trunk/include/ruby/intern.h 2010-01-26 10:42:46 UTC (rev 3337)
+++ MacRuby/trunk/include/ruby/intern.h 2010-01-26 14:18:47 UTC (rev 3338)
@@ -535,7 +535,6 @@
void ruby_incpush(const char*);
/* signal.c */
VALUE rb_f_kill(VALUE, SEL, int, VALUE*);
-void rb_gc_mark_trap_list(void);
#ifdef POSIX_SIGNAL
#define posix_signal ruby_posix_signal
RETSIGTYPE (*posix_signal(int, RETSIGTYPE (*)(int)))(int);
Modified: MacRuby/trunk/include/ruby/signal.h
===================================================================
--- MacRuby/trunk/include/ruby/signal.h 2010-01-26 10:42:46 UTC (rev 3337)
+++ MacRuby/trunk/include/ruby/signal.h 2010-01-26 14:18:47 UTC (rev 3338)
@@ -21,28 +21,8 @@
#include <errno.h>
-#ifdef _WIN32
-typedef LONG rb_atomic_t;
+typedef RETSIGTYPE (*sighandler_t)(int);
-# define ATOMIC_TEST(var) InterlockedExchange(&(var), 0)
-# define ATOMIC_SET(var, val) InterlockedExchange(&(var), (val))
-# define ATOMIC_INC(var) InterlockedIncrement(&(var))
-# define ATOMIC_DEC(var) InterlockedDecrement(&(var))
-
-/* Windows doesn't allow interrupt while system calls */
-# define TRAP_BEG do {\
- rb_atomic_t trap_immediate = ATOMIC_SET(rb_trap_immediate, 1)
-
-# define TRAP_END\
- ATOMIC_SET(rb_trap_immediate, trap_immediate);\
-} while (0)
-
-# define RUBY_CRITICAL(statements) do {\
- rb_atomic_t trap_immediate = ATOMIC_SET(rb_trap_immediate, 0);\
- statements;\
- ATOMIC_SET(rb_trap_immediate, trap_immediate);\
-} while (0)
-#else
typedef int rb_atomic_t;
# define ATOMIC_TEST(var) ((var) ? ((var) = 0, 1) : 0)
@@ -64,7 +44,6 @@
statements;\
rb_trap_immediate = trap_immediate;\
} while (0)
-#endif
RUBY_EXTERN rb_atomic_t rb_trap_immediate;
RUBY_EXTERN int rb_prohibit_interrupt;
Modified: MacRuby/trunk/signal.c
===================================================================
--- MacRuby/trunk/signal.c 2010-01-26 10:42:46 UTC (rev 3337)
+++ MacRuby/trunk/signal.c 2010-01-26 14:18:47 UTC (rev 3338)
@@ -20,164 +20,69 @@
#include "vm.h"
#include <signal.h>
#include <stdio.h>
+#include <dispatch/dispatch.h>
+#include <dispatch/queue.h>
-#ifdef __BEOS__
-#undef SIGBUS
-#endif
+#define USE_DEFAULT_HANDLER (void (*)(int))-1
-#if defined HAVE_SIGPROCMASK || defined HAVE_SIGSETMASK
-#define USE_TRAP_MASK 1
-#else
-#define USE_TRAP_MASK 0
-#endif
+static RETSIGTYPE sighandler(int sig);
-#ifndef NSIG
-# ifdef DJGPP
-# define NSIG SIGMAX
-# else
-# define NSIG (_SIGMAX + 1) /* For QNX */
-# endif
-#endif
-
static const struct signals {
const char *signm;
int signo;
} siglist [] = {
- {"EXIT", 0},
-#ifdef SIGHUP
- {"HUP", SIGHUP},
-#endif
- {"INT", SIGINT},
-#ifdef SIGQUIT
- {"QUIT", SIGQUIT},
-#endif
-#ifdef SIGILL
- {"ILL", SIGILL},
-#endif
-#ifdef SIGTRAP
- {"TRAP", SIGTRAP},
-#endif
-#ifdef SIGIOT
- {"IOT", SIGIOT},
-#endif
-#ifdef SIGABRT
- {"ABRT", SIGABRT},
-#endif
-#ifdef SIGEMT
- {"EMT", SIGEMT},
-#endif
-#ifdef SIGFPE
- {"FPE", SIGFPE},
-#endif
-#ifdef SIGKILL
- {"KILL", SIGKILL},
-#endif
-#ifdef SIGBUS
- {"BUS", SIGBUS},
-#endif
-#ifdef SIGSEGV
- {"SEGV", SIGSEGV},
-#endif
-#ifdef SIGSYS
- {"SYS", SIGSYS},
-#endif
-#ifdef SIGPIPE
- {"PIPE", SIGPIPE},
-#endif
-#ifdef SIGALRM
- {"ALRM", SIGALRM},
-#endif
-#ifdef SIGTERM
- {"TERM", SIGTERM},
-#endif
-#ifdef SIGURG
- {"URG", SIGURG},
-#endif
-#ifdef SIGSTOP
- {"STOP", SIGSTOP},
-#endif
-#ifdef SIGTSTP
- {"TSTP", SIGTSTP},
-#endif
-#ifdef SIGCONT
- {"CONT", SIGCONT},
-#endif
-#ifdef SIGCHLD
- {"CHLD", SIGCHLD},
-#endif
-#ifdef SIGCLD
- {"CLD", SIGCLD},
-#else
-# ifdef SIGCHLD
- {"CLD", SIGCHLD},
-# endif
-#endif
-#ifdef SIGTTIN
- {"TTIN", SIGTTIN},
-#endif
-#ifdef SIGTTOU
- {"TTOU", SIGTTOU},
-#endif
-#ifdef SIGIO
- {"IO", SIGIO},
-#endif
-#ifdef SIGXCPU
- {"XCPU", SIGXCPU},
-#endif
-#ifdef SIGXFSZ
- {"XFSZ", SIGXFSZ},
-#endif
-#ifdef SIGVTALRM
+ {"EXIT", 0},
+ {"HUP", SIGHUP},
+ {"INT", SIGINT},
+ {"QUIT", SIGQUIT},
+ {"ILL", SIGILL},
+ {"TRAP", SIGTRAP},
+ {"IOT", SIGIOT},
+ {"ABRT", SIGABRT},
+ {"EMT", SIGEMT},
+ {"FPE", SIGFPE},
+ {"KILL", SIGKILL},
+ {"BUS", SIGBUS},
+ {"SEGV", SIGSEGV},
+ {"SYS", SIGSYS},
+ {"PIPE", SIGPIPE},
+ {"ALRM", SIGALRM},
+ {"TERM", SIGTERM},
+ {"URG", SIGURG},
+ {"STOP", SIGSTOP},
+ {"TSTP", SIGTSTP},
+ {"CONT", SIGCONT},
+ {"CHLD", SIGCHLD},
+ {"CLD", SIGCHLD},
+ {"TTIN", SIGTTIN},
+ {"TTOU", SIGTTOU},
+ {"IO", SIGIO},
+ {"XCPU", SIGXCPU},
+ {"XFSZ", SIGXFSZ},
{"VTALRM", SIGVTALRM},
-#endif
-#ifdef SIGPROF
- {"PROF", SIGPROF},
-#endif
-#ifdef SIGWINCH
- {"WINCH", SIGWINCH},
-#endif
-#ifdef SIGUSR1
- {"USR1", SIGUSR1},
-#endif
-#ifdef SIGUSR2
- {"USR2", SIGUSR2},
-#endif
-#ifdef SIGLOST
- {"LOST", SIGLOST},
-#endif
-#ifdef SIGMSG
- {"MSG", SIGMSG},
-#endif
-#ifdef SIGPWR
- {"PWR", SIGPWR},
-#endif
-#ifdef SIGPOLL
- {"POLL", SIGPOLL},
-#endif
-#ifdef SIGDANGER
- {"DANGER", SIGDANGER},
-#endif
-#ifdef SIGMIGRATE
- {"MIGRATE", SIGMIGRATE},
-#endif
-#ifdef SIGPRE
- {"PRE", SIGPRE},
-#endif
-#ifdef SIGGRANT
- {"GRANT", SIGGRANT},
-#endif
-#ifdef SIGRETRACT
- {"RETRACT", SIGRETRACT},
-#endif
-#ifdef SIGSOUND
- {"SOUND", SIGSOUND},
-#endif
-#ifdef SIGINFO
- {"INFO", SIGINFO},
-#endif
+ {"PROF", SIGPROF},
+ {"WINCH", SIGWINCH},
+ {"INFO", SIGINFO},
+ {"USR1", SIGUSR1},
+ {"USR2", SIGUSR2},
{NULL, 0}
};
+static const struct trap_handlers {
+ const char *command;
+ VALUE new_cmd_value;
+ sighandler_t handler;
+} gl_trap_handlers[] = {
+ {"SYSTEM_DEFAULT", 0, SIG_DFL},
+ {"SIG_IGN", 0, SIG_IGN},
+ {"IGNORE", 0, SIG_IGN},
+ {"", 0, SIG_IGN},
+ {"SIG_DFL", 0, USE_DEFAULT_HANDLER},
+ {"DEFAULT", 0, USE_DEFAULT_HANDLER},
+ {"EXIT", Qundef, sighandler},
+ {NULL, 0}
+ };
+
static int
signm2signo(const char *nm)
{
@@ -285,7 +190,6 @@
args[0] = INT2FIX(SIGINT);
rb_scan_args(argc, argv, "01", &args[1]);
- //return rb_call_super(2, args);
return rb_vm_call(self, selInitialize2, 2, args, true);
}
@@ -325,82 +229,68 @@
VALUE
rb_f_kill(VALUE self, SEL sel, int argc, VALUE *argv)
{
-#ifndef HAS_KILLPG
-#define killpg(pg, sig) kill(-(pg), sig)
-#endif
int negative = 0;
int sig;
int i;
- const char *s;
+ int type;
+ const char *s = NULL;
rb_secure(2);
if (argc < 2)
rb_raise(rb_eArgError, "wrong number of arguments -- kill(sig, pid...)");
- switch (TYPE(argv[0])) {
- case T_FIXNUM:
- sig = FIX2INT(argv[0]);
- break;
- case T_SYMBOL:
- s = rb_sym2name(argv[0]);
- if (!s) rb_raise(rb_eArgError, "bad signal");
- goto str_signal;
-
- case T_STRING:
- s = RSTRING_PTR(argv[0]);
- if (s[0] == '-') {
- negative++;
- s++;
+ type = TYPE(argv[0]);
+ if (type == T_FIXNUM) {
+ sig = FIX2INT(argv[0]);
+ }
+ else {
+ if (type == T_SYMBOL) {
+ s = rb_sym2name(argv[0]);
+ if (!s)
+ rb_raise(rb_eArgError, "bad signal");
}
- str_signal:
- if (strncmp("SIG", s, 3) == 0)
- s += 3;
- if((sig = signm2signo(s)) == 0)
- rb_raise(rb_eArgError, "unsupported name `SIG%s'", s);
-
- if (negative)
- sig = -sig;
- break;
-
- default:
- {
+ else if (type == T_STRING) {
+ s = RSTRING_PTR(argv[0]);
+ if (s[0] == '-') {
+ negative++;
+ s++;
+ }
+ }
+ else {
VALUE str;
-
str = rb_check_string_type(argv[0]);
if (!NIL_P(str)) {
s = RSTRING_PTR(str);
- goto str_signal;
}
- rb_raise(rb_eArgError, "bad signal type %s",
- rb_obj_classname(argv[0]));
}
- break;
+ if (s == NULL)
+ rb_raise(rb_eArgError, "bad signal type %s", rb_obj_classname(argv[0]));
+
+ if (strncmp("SIG", s, 3) == 0)
+ s += 3;
+ if ((sig = signm2signo(s)) == 0)
+ rb_raise(rb_eArgError, "unsupported name `SIG%s'", s);
+ if (negative)
+ sig = -sig;
}
if (sig < 0) {
sig = -sig;
- for (i=1; i<argc; i++) {
+ for (i = 1; i < argc; i++) {
if (killpg(NUM2PIDT(argv[i]), sig) < 0)
rb_sys_fail(0);
}
}
else {
- for (i=1; i<argc; i++) {
+ for (i = 1; i < argc; i++) {
if (kill(NUM2PIDT(argv[i]), sig) < 0)
rb_sys_fail(0);
}
}
rb_thread_polling();
- return INT2FIX(i-1);
+ return INT2FIX(i - 1);
}
-static struct {
- VALUE cmd;
-} trap_list[NSIG];
-static rb_atomic_t trap_pending_list[NSIG];
-#if 0
-static char rb_trap_accept_nativethreads[NSIG];
-#endif
rb_atomic_t rb_trap_pending;
rb_atomic_t rb_trap_immediate;
int rb_prohibit_interrupt = 1;
@@ -408,7 +298,7 @@
VALUE
rb_get_trap_cmd(int sig)
{
- return trap_list[sig].cmd;
+ return rb_vm_trap_cmd_for_signal(sig);
}
void
@@ -417,43 +307,33 @@
#ifndef MACOS_UNUSE_SIGNAL
int i;
- for (i=0; i<NSIG; i++) {
- if (trap_list[i].cmd) {
- rb_gc_mark(trap_list[i].cmd);
+ for (i = 0; i < NSIG; i++) {
+ if (rb_vm_trap_cmd_for_signal(i)) {
+ rb_gc_mark(rb_vm_trap_cmd_for_signal(i));
}
}
#endif /* MACOS_UNUSE_SIGNAL */
}
-#ifdef __dietlibc__
-#define sighandler_t sh_t
-#endif
-
-typedef RETSIGTYPE (*sighandler_t)(int);
-
-static sighandler_t
+sighandler_t
ruby_signal(int signum, sighandler_t handler)
{
- struct sigaction sigact, old;
+ struct sigaction sigact;
+ struct sigaction old;
-#if 0
- rb_trap_accept_nativethreads[signum] = 0;
-#endif
-
sigemptyset(&sigact.sa_mask);
-#ifdef SA_SIGINFO
- sigact.sa_sigaction = (void (*)(int, siginfo_t*, void*))handler;
- sigact.sa_flags = SA_SIGINFO;
-#else
sigact.sa_handler = handler;
sigact.sa_flags = 0;
-#endif
-#ifdef SA_NOCLDWAIT
if (signum == SIGCHLD && handler == SIG_IGN)
sigact.sa_flags |= SA_NOCLDWAIT;
-#endif
- sigaction(signum, &sigact, &old);
+ if (signum == SIGSEGV)
+ sigact.sa_flags |= SA_ONSTACK;
+ if (sigaction(signum, &sigact, &old) < 0) {
+ if (errno != 0 && errno != EINVAL) {
+ rb_bug("sigaction error.\n");
+ }
+ }
return old.sa_handler;
}
@@ -463,131 +343,83 @@
return ruby_signal(signum, handler);
}
+static void signal_exec(VALUE cmd, int level, int sig);
+static void rb_signal_exec(int sig);
+
static RETSIGTYPE
sighandler(int sig)
{
-#if 0
- rb_vm_t *vm = GET_VM(); /* fix me for Multi-VM */
- ATOMIC_INC(vm->signal_buff[sig]);
- ATOMIC_INC(vm->buffered_signal_size);
-#endif
-
-printf("sighandler %d\n", sig);
-
-//#if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
-printf("ruby signal\n");
+ int olderrno = errno;
+ rb_signal_exec(sig);
ruby_signal(sig, sighandler);
-//#endif
+ errno = olderrno;
}
-#if USE_TRAP_MASK
-# ifdef HAVE_SIGPROCMASK
-static sigset_t trap_last_mask;
-# else
-static int trap_last_mask;
-# endif
-#endif
-
-#if HAVE_PTHREAD_H
#include <pthread.h>
-#endif
void
rb_disable_interrupt(void)
{
-#ifndef _WIN32
sigset_t mask;
sigfillset(&mask);
sigdelset(&mask, SIGVTALRM);
sigdelset(&mask, SIGSEGV);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
-#endif
}
void
rb_enable_interrupt(void)
{
-#ifndef _WIN32
sigset_t mask;
sigemptyset(&mask);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
-#endif
}
-#if 0 // XXX unused function
-int
-rb_get_next_signal(rb_vm_t *vm)
-{
- int i, sig = 0;
-
- for (i=1; i<RUBY_NSIG; i++) {
- if (vm->signal_buff[i] > 0) {
- rb_disable_interrupt();
- {
- ATOMIC_DEC(vm->signal_buff[i]);
- ATOMIC_DEC(vm->buffered_signal_size);
- }
- rb_enable_interrupt();
- sig = i;
- break;
- }
- }
- return sig;
-}
-#endif
-
-#ifdef SIGBUS
static RETSIGTYPE
sigbus(int sig)
{
rb_bug("Bus Error");
}
-#endif
-#ifdef SIGSEGV
static int segv_received = 0;
static RETSIGTYPE
sigsegv(int sig)
{
if (segv_received) {
fprintf(stderr, "SEGV recieved in SEGV handler\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
else {
segv_received = 1;
rb_bug("Segmentation fault");
}
}
-#endif
-#ifdef SIGPIPE
static RETSIGTYPE
sigpipe(int sig)
{
/* do nothing */
}
-#endif
static void
-signal_exec(VALUE cmd, int sig)
+signal_exec(VALUE cmd, int level, int sig)
{
-#if 0 // TODO
- rb_proc_t *proc;
- VALUE signum = INT2FIX(sig);
- GetProcPtr(cmd, proc);
- vm_invoke_proc(GET_THREAD(), proc, proc->block.self, 1, &signum, 0);
-#endif
+ VALUE signum = INT2NUM(sig);
+ rb_eval_cmd(cmd, rb_ary_new3(1, signum), level);
}
void
rb_trap_exit(void)
{
#ifndef MACOS_UNUSE_SIGNAL
- if (trap_list[0].cmd) {
- VALUE trap_exit = trap_list[0].cmd;
+ VALUE trap_exit;
+ int safe;
- trap_list[0].cmd = 0;
- signal_exec(trap_exit, 0);
+ trap_exit = rb_vm_trap_cmd_for_signal(0);
+ if (trap_exit != (VALUE)NULL) {
+ safe = rb_vm_trap_level_for_signal(0);
+ rb_vm_set_trap_for_signal((VALUE)0, safe, 0);
+ signal_exec(trap_exit, safe, 0);
}
#endif
}
@@ -595,6 +427,8 @@
static void
rb_signal_exec(int sig)
{
+/* rb_vm_thread_t *t; */
+/* VALUE exc; */
VALUE cmd = rb_get_trap_cmd(sig);
if (cmd == 0) {
@@ -602,60 +436,28 @@
case SIGINT:
rb_interrupt();
break;
-#ifdef SIGHUP
case SIGHUP:
-#endif
-#ifdef SIGQUIT
case SIGQUIT:
-#endif
-#ifdef SIGTERM
case SIGTERM:
-#endif
-#ifdef SIGALRM
case SIGALRM:
-#endif
-#ifdef SIGUSR1
case SIGUSR1:
-#endif
-#ifdef SIGUSR2
case SIGUSR2:
-#endif
- //rb_thread_signal_raise(th, sig);
+/* t = GetThreadPtr(rb_vm_main_thread()); */
+/* exc = rb_exc_new2(rb_eSignal, ruby_signal_name(sig)); */
+/* rb_vm_thread_raise(t, exc); */
+/* rb_raise(rb_eSignal, "%s", signo2signm(sig)); */
break;
}
}
else if (cmd == Qundef) {
-// rb_thread_signal_exit(th);
+ //rb_thread_signal_exit(th);
}
else {
- signal_exec(cmd, sig);
+ signal_exec(cmd, rb_vm_trap_level_for_signal(sig), sig);
}
}
-void
-rb_trap_exec(void)
-{
-#ifndef MACOS_UNUSE_SIGNAL
- int i;
-
- for (i=0; i<NSIG; i++) {
- if (trap_pending_list[i]) {
- trap_pending_list[i] = 0;
- rb_signal_exec(i);
- }
- }
-#endif /* MACOS_UNUSE_SIGNAL */
- rb_trap_pending = 0;
-}
-
struct trap_arg {
-#if USE_TRAP_MASK
-# ifdef HAVE_SIGPROCMASK
- sigset_t mask;
-# else
- int mask;
-# endif
-#endif
int sig;
sighandler_t func;
VALUE cmd;
@@ -667,41 +469,23 @@
sighandler_t func;
switch (sig) {
case SIGINT:
-#ifdef SIGHUP
case SIGHUP:
-#endif
-#ifdef SIGQUIT
case SIGQUIT:
-#endif
-#ifdef SIGTERM
case SIGTERM:
-#endif
-#ifdef SIGALRM
case SIGALRM:
-#endif
-#ifdef SIGUSR1
case SIGUSR1:
-#endif
-#ifdef SIGUSR2
case SIGUSR2:
-#endif
func = sighandler;
break;
-#ifdef SIGBUS
case SIGBUS:
func = sigbus;
break;
-#endif
-#ifdef SIGSEGV
case SIGSEGV:
- func = sigsegv;
+ func = (sighandler_t)sigsegv;
break;
-#endif
-#ifdef SIGPIPE
case SIGPIPE:
func = sigpipe;
break;
-#endif
default:
func = SIG_DFL;
break;
@@ -710,15 +494,10 @@
return func;
}
-static RETSIGTYPE
-wrong_trap(int sig)
-{
-}
-
static sighandler_t
trap_handler(VALUE *cmd, int sig)
{
- sighandler_t func = wrong_trap;
+ sighandler_t func = sighandler;
VALUE command;
if (NIL_P(*cmd)) {
@@ -726,55 +505,26 @@
}
else {
command = rb_check_string_type(*cmd);
+ if (NIL_P(command) && SYMBOL_P(*cmd)) {
+ command = rb_id2str(SYM2ID(*cmd));
+ if (!command) rb_raise(rb_eArgError, "bad handler");
+ }
if (!NIL_P(command)) {
SafeStringValue(command); /* taint check */
- switch (RSTRING_LEN(command)) {
- case 0:
- goto sig_ign;
- break;
- case 14:
- if (strncmp(RSTRING_PTR(command), "SYSTEM_DEFAULT", 14) == 0) {
- func = SIG_DFL;
- *cmd = 0;
+ *cmd = command;
+ for (int i = 0; gl_trap_handlers[i].command != NULL; i++) {
+ if (strcmp(gl_trap_handlers[i].command, RSTRING_PTR(command)) == 0) {
+ func = gl_trap_handlers[i].handler;
+ if (func == USE_DEFAULT_HANDLER) {
+ func = default_handler(sig);
+ }
+ *cmd = gl_trap_handlers[i].new_cmd_value;
+ break;
}
- break;
- case 7:
- if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) {
-sig_ign:
- func = SIG_IGN;
- *cmd = 0;
- }
- else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) {
-sig_dfl:
- func = default_handler(sig);
- *cmd = 0;
- }
- else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) {
- goto sig_dfl;
- }
- break;
- case 6:
- if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) {
- goto sig_ign;
- }
- break;
- case 4:
- if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) {
- func = sighandler;
- *cmd = Qundef;
- }
- break;
}
- if (func == wrong_trap) {
- rb_raise(rb_eArgError, "wrong trap - %s", RSTRING_PTR(command));
- }
}
else {
-#if 0 // TODO
- rb_proc_t *proc;
- GetProcPtr(*cmd, proc);
-#endif
- func = sighandler;
+/* func = sighandler; */
}
}
@@ -787,23 +537,21 @@
int sig = -1;
const char *s;
- switch (TYPE(vsig)) {
- case T_FIXNUM:
+ if (TYPE(vsig) == T_FIXNUM) {
sig = FIX2INT(vsig);
if (sig < 0 || sig >= NSIG) {
rb_raise(rb_eArgError, "invalid signal number (%d)", sig);
}
- break;
+ }
+ else {
+ if (TYPE(vsig) == T_SYMBOL) {
+ s = rb_sym2name(vsig);
+ if (s == NULL)
+ rb_raise(rb_eArgError, "bad signal");
+ }
+ else
+ s = StringValuePtr(vsig);
- case T_SYMBOL:
- s = rb_sym2name(vsig);
- if (!s) rb_raise(rb_eArgError, "bad signal");
- goto str_signal;
-
- default:
- s = StringValuePtr(vsig);
-
- str_signal:
if (strncmp("SIG", s, 3) == 0)
s += 3;
sig = signm2signo(s);
@@ -816,60 +564,34 @@
static VALUE
trap(struct trap_arg *arg)
{
- sighandler_t oldfunc, func = arg->func;
- VALUE oldcmd, command = arg->cmd;
+ sighandler_t oldfunc;
+ sighandler_t func = arg->func;
+ VALUE oldcmd;
+ VALUE command = arg->cmd;
int sig = arg->sig;
oldfunc = ruby_signal(sig, func);
- oldcmd = trap_list[sig].cmd;
- switch (oldcmd) {
- case 0:
- if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE");
- else if (oldfunc == sighandler) oldcmd = rb_str_new2("DEFAULT");
- else oldcmd = Qnil;
- break;
- case Qundef:
- oldcmd = rb_str_new2("EXIT");
- break;
+ oldcmd = rb_vm_trap_cmd_for_signal(sig);
+ if (oldcmd == 0) {
+ if (oldfunc == SIG_IGN)
+ oldcmd = rb_str_new2("IGNORE");
+ else if (oldfunc == sighandler)
+ oldcmd = rb_str_new2("DEFAULT");
+ else
+ oldcmd = Qnil;
}
+ else if (oldcmd == Qundef)
+ oldcmd = rb_str_new2("EXIT");
- trap_list[sig].cmd = command;
- /* enable at least specified signal. */
-#if USE_TRAP_MASK
-#ifdef HAVE_SIGPROCMASK
- sigdelset(&arg->mask, sig);
-#else
- arg->mask &= ~sigmask(sig);
-#endif
-#endif
+ // Assign trap to signal
+ rb_vm_set_trap_for_signal(command, rb_safe_level(), sig);
+
return oldcmd;
}
-#if USE_TRAP_MASK
-static VALUE
-trap_ensure(struct trap_arg *arg)
-{
- /* enable interrupt */
-#ifdef HAVE_SIGPROCMASK
- sigprocmask(SIG_SETMASK, &arg->mask, NULL);
-#else
- sigsetmask(arg->mask);
-#endif
- trap_last_mask = arg->mask;
- return 0;
-}
-#endif
-
void
rb_trap_restore_mask(void)
{
-#if USE_TRAP_MASK
-# ifdef HAVE_SIGPROCMASK
- sigprocmask(SIG_SETMASK, &trap_last_mask, NULL);
-# else
- sigsetmask(trap_last_mask);
-# endif
-#endif
}
/*
@@ -903,6 +625,7 @@
* Child died
* Terminating: 27460
*/
+
static VALUE
sig_trap(VALUE rcv, SEL sel, int argc, VALUE *argv)
{
@@ -918,7 +641,7 @@
arg.cmd = rb_block_proc();
arg.func = sighandler;
}
- else if (argc == 2) {
+ else {
arg.cmd = argv[1];
arg.func = trap_handler(&arg.cmd, arg.sig);
}
@@ -926,19 +649,8 @@
if (OBJ_TAINTED(arg.cmd)) {
rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
}
-#if USE_TRAP_MASK
- /* disable interrupt */
-# ifdef HAVE_SIGPROCMASK
- sigfillset(&arg.mask);
- sigprocmask(SIG_BLOCK, &arg.mask, &arg.mask);
-# else
- arg.mask = sigblock(~0);
-# endif
- return rb_ensure(trap, (VALUE)&arg, trap_ensure, (VALUE)&arg);
-#else
return trap(&arg);
-#endif
}
/*
@@ -962,7 +674,6 @@
return h;
}
-#if 0
static void
install_sighandler(int signum, sighandler_t handler)
{
@@ -973,48 +684,19 @@
ruby_signal(signum, old);
}
}
-#endif
#if defined(SIGCLD) || defined(SIGCHLD)
static void
init_sigchld(int sig)
{
sighandler_t oldfunc;
-#if USE_TRAP_MASK
-# ifdef HAVE_SIGPROCMASK
- sigset_t mask;
-# else
- int mask;
-# endif
-#endif
-#if USE_TRAP_MASK
- /* disable interrupt */
-# ifdef HAVE_SIGPROCMASK
- sigfillset(&mask);
- sigprocmask(SIG_BLOCK, &mask, &mask);
-# else
- mask = sigblock(~0);
-# endif
-#endif
-
oldfunc = ruby_signal(sig, SIG_DFL);
if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) {
ruby_signal(sig, oldfunc);
} else {
- trap_list[sig].cmd = 0;
+ rb_vm_set_trap_for_signal((VALUE)0, rb_safe_level(), sig);
}
-
-#if USE_TRAP_MASK
-#ifdef HAVE_SIGPROCMASK
- sigdelset(&mask, sig);
- sigprocmask(SIG_SETMASK, &mask, NULL);
-#else
- mask &= ~sigmask(sig);
- sigsetmask(mask);
-#endif
- trap_last_mask = mask;
-#endif
}
#endif
@@ -1029,7 +711,6 @@
}
}
-
#ifdef RUBY_DEBUG_ENV
int ruby_enable_coredump = 0;
#endif
@@ -1086,48 +767,23 @@
rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message"));
rb_objc_define_method(rb_eInterrupt, "initialize", interrupt_init, -1);
-#if 0
- install_sighandler(SIGINT, sighandler);
-#ifdef SIGHUP
- install_sighandler(SIGHUP, sighandler);
-#endif
-#ifdef SIGQUIT
- install_sighandler(SIGQUIT, sighandler);
-#endif
-#ifdef SIGTERM
- install_sighandler(SIGTERM, sighandler);
-#endif
-#ifdef SIGALRM
- install_sighandler(SIGALRM, sighandler);
-#endif
-#ifdef SIGUSR1
- install_sighandler(SIGUSR1, sighandler);
-#endif
-#ifdef SIGUSR2
- install_sighandler(SIGUSR2, sighandler);
-#endif
+/* install_sighandler(SIGINT, sighandler); */
+/* install_sighandler(SIGHUP, sighandler); */
+/* install_sighandler(SIGQUIT, sighandler); */
+/* install_sighandler(SIGTERM, sighandler); */
+/* install_sighandler(SIGALRM, sighandler); */
+/* install_sighandler(SIGUSR1, sighandler); */
+/* install_sighandler(SIGUSR2, sighandler); */
#ifdef RUBY_DEBUG_ENV
if (!ruby_enable_coredump)
#endif
{
-#ifdef SIGBUS
- install_sighandler(SIGBUS, sigbus);
-#endif
-#ifdef SIGSEGV
- install_sighandler(SIGSEGV, sigsegv);
-#endif
+ install_sighandler(SIGBUS, sigbus);
+ install_sighandler(SIGSEGV, sigsegv);
}
-#ifdef SIGPIPE
install_sighandler(SIGPIPE, sigpipe);
-#endif
-#endif
-#if defined(SIGCLD)
- init_sigchld(SIGCLD);
-#elif defined(SIGCHLD)
init_sigchld(SIGCHLD);
-#endif
-
-#endif /* MACOS_UNUSE_SIGNAL */
+#endif /* !MACOS_UNUSE_SIGNAL */
}
Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp 2010-01-26 10:42:46 UTC (rev 3337)
+++ MacRuby/trunk/vm.cpp 2010-01-26 14:18:47 UTC (rev 3338)
@@ -30,6 +30,7 @@
#include <llvm/Target/TargetSelect.h>
#include <llvm/Transforms/Scalar.h>
#include <llvm/Support/raw_ostream.h>
+#include <llvm/Support/PrettyStackTrace.h> // Including PST to disable it
#include <llvm/Intrinsics.h>
#include <llvm/Bitcode/ReaderWriter.h>
#if LLVM_TOT
@@ -1099,7 +1100,68 @@
core->unlock();
}
+VALUE
+RoxorCore::trap_cmd_for_signal(int signal)
+{
+ VALUE trap;
+
+ this->lock();
+ trap = this->trap_cmd[signal];
+ this->unlock();
+
+ return trap;
+}
+
extern "C"
+VALUE
+rb_vm_trap_cmd_for_signal(int signal)
+{
+ return GET_CORE()->trap_cmd_for_signal(signal);
+}
+
+int
+RoxorCore::trap_level_for_signal(int signal)
+{
+ VALUE trap;
+
+ this->lock();
+ trap = this->trap_level[signal];
+ this->unlock();
+
+ return trap;
+}
+
+extern "C"
+int
+rb_vm_trap_level_for_signal(int signal)
+{
+ return GET_CORE()->trap_level_for_signal(signal);
+}
+
+void
+RoxorCore::set_trap_for_signal(VALUE trap, int level, int signal)
+{
+ VALUE oldtrap;
+
+ this->lock();
+ oldtrap = this->trap_cmd[signal];
+ if (oldtrap != trap) {
+ GC_RELEASE(oldtrap);
+ GC_RETAIN(trap);
+ this->trap_cmd[signal] = trap;
+ this->trap_level[signal] = level;
+ }
+ this->unlock();
+}
+
+extern "C"
+void
+rb_vm_set_trap_for_signal(VALUE trap, int level, int signal)
+{
+ GET_CORE()->set_trap_for_signal(trap, level, signal);
+}
+
+extern "C"
bool
rb_vm_abort_on_exception(void)
{
@@ -4763,6 +4825,8 @@
{
llvm::DwarfExceptionHandling = true; // required!
llvm::JITEmitDebugInfo = true;
+ // because pretty stack trace uses signal handling and thus breaks ours
+ llvm::DisablePrettyStackTrace = true;
RoxorCompiler::module = new llvm::Module("Roxor", getGlobalContext());
RoxorCompiler::module->setTargetTriple(TARGET_TRIPLE);
Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h 2010-01-26 10:42:46 UTC (rev 3337)
+++ MacRuby/trunk/vm.h 2010-01-26 14:18:47 UTC (rev 3338)
@@ -270,6 +270,9 @@
void rb_vm_set_parse_in_eval(bool flag);
VALUE rb_vm_load_path(void);
VALUE rb_vm_loaded_features(void);
+VALUE rb_vm_trap_cmd_for_signal(int signal);
+int rb_vm_trap_level_for_signal(int signal);
+void rb_vm_set_trap_for_signal(VALUE trap, int level, int signal);
int rb_vm_safe_level(void);
void rb_vm_set_safe_level(int level);
int rb_vm_thread_safe_level(rb_vm_thread_t *thread);
@@ -606,6 +609,11 @@
VALUE load_path;
VALUE rand_seed;
+ // Signals
+ std::map<int, VALUE> trap_cmd;
+ // Safety level at the time trap is set
+ std::map<int, int> trap_level;
+
// Cache to avoid compiling the same Function twice.
std::map<Function *, IMP> JITcache;
@@ -673,6 +681,11 @@
READER(functions_compiled, long);
#endif
+ // signals
+ void set_trap_for_signal(VALUE trap, int level, int signal);
+ VALUE trap_cmd_for_signal(int signal);
+ int trap_level_for_signal(int signal);
+
void lock(void) {
if (multithreaded) {
assert(pthread_mutex_lock(&gl) == 0);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100126/df4e3aa1/attachment-0001.html>
More information about the macruby-changes
mailing list