1
0
Fork 0
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:
nagai 2006-07-10 05:02:00 +00:00
parent 09ac765b2f
commit 5ed246f1d3
4 changed files with 155 additions and 11 deletions

View file

@ -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
View file

@ -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
View file

@ -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
View file

@ -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;