mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* signal.c (ruby_nativethread_signal, posix_nativethread_signal,
sigsend_to_ruby_thread, install_nativethread_sighandler): nativethread-support on signal handler. RE-backport from 1.9. * ruby.h (HAVE_NATIVETHREAD_KILL): ditto. * eval.c (ruby_native_thread_kill): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@10502 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
09ac765b2f
commit
5ed246f1d3
4 changed files with 155 additions and 11 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Mon Jul 10 13:58:40 2006 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||
|
||||
* signal.c (ruby_nativethread_signal, posix_nativethread_signal,
|
||||
sigsend_to_ruby_thread, install_nativethread_sighandler):
|
||||
nativethread-support on signal handler. RE-backport from 1.9.
|
||||
|
||||
* ruby.h (HAVE_NATIVETHREAD_KILL): ditto.
|
||||
|
||||
* eval.c (ruby_native_thread_kill): ditto.
|
||||
|
||||
Mon Jul 10 10:54:14 2006 Ryan Davis <ryand@zenspider.com>
|
||||
|
||||
* lib/rdoc/parsers/parse_f95.rb: massive overhaul from Yasuhiro
|
||||
|
|
9
eval.c
9
eval.c
|
@ -1343,6 +1343,15 @@ int
|
|||
is_ruby_native_thread() {
|
||||
return NATIVETHREAD_EQUAL(ruby_thid, NATIVETHREAD_CURRENT());
|
||||
}
|
||||
|
||||
# ifdef HAVE_NATIVETHREAD_KILL
|
||||
void
|
||||
ruby_native_thread_kill(sig)
|
||||
int sig;
|
||||
{
|
||||
NATIVETHREAD_KILL(ruby_thid, sig);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
void
|
||||
|
|
8
ruby.h
8
ruby.h
|
@ -696,6 +696,9 @@ typedef pthread_t rb_nativethread_t;
|
|||
# define NATIVETHREAD_CURRENT() pthread_self()
|
||||
# define NATIVETHREAD_EQUAL(t1,t2) pthread_equal((t1),(t2))
|
||||
# define HAVE_NATIVETHREAD
|
||||
|
||||
# define NATIVETHREAD_KILL(th,sig) pthread_kill((th),(sig))
|
||||
# define HAVE_NATIVETHREAD_KILL
|
||||
#elif defined(_WIN32) || defined(_WIN32_WCE)
|
||||
typedef DWORD rb_nativethread_t;
|
||||
# define NATIVETHREAD_CURRENT() GetCurrentThreadId()
|
||||
|
@ -703,10 +706,13 @@ typedef DWORD rb_nativethread_t;
|
|||
# define HAVE_NATIVETHREAD
|
||||
#endif
|
||||
#ifdef HAVE_NATIVETHREAD
|
||||
RUBY_EXTERN int is_ruby_native_thread();
|
||||
int is_ruby_native_thread _((void));
|
||||
#else
|
||||
#define is_ruby_native_thread() (1)
|
||||
#endif
|
||||
#ifdef HAVE_NATIVETHREAD_KILL
|
||||
void ruby_native_thread_kill _((int));
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#if 0
|
||||
|
|
139
signal.c
139
signal.c
|
@ -304,6 +304,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;
|
||||
|
@ -335,21 +336,23 @@ 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;
|
||||
#if defined(SA_RESTART)
|
||||
# if defined(SA_RESTART)
|
||||
/* All other signals but VTALRM shall restart restartable syscall
|
||||
VTALRM will cause EINTR to syscall if interrupted.
|
||||
*/
|
||||
if (signum != SIGVTALRM) {
|
||||
sigact.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */
|
||||
}
|
||||
#endif
|
||||
#ifdef SA_NOCLDWAIT
|
||||
# endif
|
||||
# ifdef SA_NOCLDWAIT
|
||||
if (signum == SIGCHLD && handler == SIG_IGN)
|
||||
sigact.sa_flags |= SA_NOCLDWAIT;
|
||||
#endif
|
||||
# endif
|
||||
sigaction(signum, &sigact, &old);
|
||||
return old.sa_handler;
|
||||
}
|
||||
|
@ -361,9 +364,46 @@ posix_signal(signum, handler)
|
|||
{
|
||||
ruby_signal(signum, handler);
|
||||
}
|
||||
#else
|
||||
#define ruby_signal(sig,handler) signal((sig),(handler))
|
||||
#endif
|
||||
|
||||
# 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
|
||||
static sighandler_t
|
||||
ruby_nativethread_signal(signum, handler)
|
||||
int signum;
|
||||
sighandler_t handler;
|
||||
{
|
||||
sighandler_t old;
|
||||
|
||||
old = signal(signum, handler);
|
||||
rb_trap_accept_nativethreads[signum] = 1;
|
||||
return old;
|
||||
}
|
||||
# endif
|
||||
#endif /* POSIX_SIGNAL */
|
||||
|
||||
static void signal_exec _((int sig));
|
||||
static void
|
||||
|
@ -394,11 +434,36 @@ signal_exec(sig)
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (trap_list[sig].cmd == Qundef) {
|
||||
rb_thread_signal_exit();
|
||||
}
|
||||
else {
|
||||
rb_thread_trap_eval(trap_list[sig].cmd, sig, trap_list[sig].safe);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)
|
||||
static void
|
||||
sigsend_to_ruby_thread(int sig)
|
||||
{
|
||||
# ifdef HAVE_SIGPROCMASK
|
||||
sigset_t mask, old_mask;
|
||||
# else
|
||||
int mask, old_mask;
|
||||
# endif
|
||||
|
||||
# ifdef HAVE_SIGPROCMASK
|
||||
sigfillset(&mask);
|
||||
sigprocmask(SIG_BLOCK, &mask, &old_mask);
|
||||
# else
|
||||
mask = sigblock(~0);
|
||||
sigsetmask(mask);
|
||||
# endif
|
||||
|
||||
ruby_native_thread_kill(sig);
|
||||
}
|
||||
#endif
|
||||
|
||||
static RETSIGTYPE sighandler _((int));
|
||||
static RETSIGTYPE
|
||||
sighandler(sig)
|
||||
|
@ -414,11 +479,22 @@ sighandler(sig)
|
|||
rb_bug("trap_handler: Bad signal %d", sig);
|
||||
}
|
||||
|
||||
#if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
|
||||
ruby_signal(sig, sighandler);
|
||||
#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)
|
||||
if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {
|
||||
sigsend_to_ruby_thread(sig);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ATOMIC_TEST(rb_trap_immediate)) {
|
||||
#if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
|
||||
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)) {
|
||||
IN_MAIN_CONTEXT(signal_exec, sig);
|
||||
ATOMIC_SET(rb_trap_immediate, 1);
|
||||
}
|
||||
|
@ -434,6 +510,13 @@ static RETSIGTYPE
|
|||
sigbus(sig)
|
||||
int sig;
|
||||
{
|
||||
#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)
|
||||
if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {
|
||||
sigsend_to_ruby_thread(sig);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
rb_bug("Bus Error");
|
||||
}
|
||||
#endif
|
||||
|
@ -444,6 +527,13 @@ static RETSIGTYPE
|
|||
sigsegv(sig)
|
||||
int sig;
|
||||
{
|
||||
#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)
|
||||
if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {
|
||||
sigsend_to_ruby_thread(sig);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
rb_bug("Segmentation fault");
|
||||
}
|
||||
#endif
|
||||
|
@ -772,6 +862,35 @@ install_sighandler(signum, handler)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* If you write a handler which works on any native thread
|
||||
* (even if the thread is NOT a ruby's one), please enable
|
||||
* this function and use it to install the handler, instead
|
||||
* of `install_sighandler()'.
|
||||
*/
|
||||
#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
|
||||
#endif
|
||||
|
||||
static void
|
||||
init_sigchld(sig)
|
||||
int sig;
|
||||
|
|
Loading…
Add table
Reference in a new issue