[#25636] [Oniguruma 3.X] reggnu.c — "K.Kosako" <sndgk393@...>

さっき気がついたのですが、元々は

15 messages 2005/02/05

[#25655] openssl binding for SSL_CTX_set_default_verify_paths and X509_STORE_set_default_paths — Tanaka Akira <akr@...17n.org>

open-uri で https を扱うことを考えていろいろと調べていた所、openssl で、

9 messages 2005/02/08
[#25670] Re: openssl binding for SSL_CTX_set_default_verify_paths and X509_STORE_set_default_paths — GOTOU Yuuzou <gotoyuzo@...> 2005/02/10

In message <876513vce0.fsf@serein.a02.aist.go.jp>,

[#25713] pthread trouble on sighandler — Hidetoshi NAGAI <nagai@...>

永井@知能.九工大です.

17 messages 2005/02/18
[#25714] Re: pthread trouble on sighandler — Yukihiro Matsumoto <matz@...> 2005/02/18

まつもと ゆきひろです

[#25755] I/O operation differs signal handler — Minero Aoki <aamine@...>

青木です。

14 messages 2005/02/24
[#25756] Re: I/O operation differs signal handler — Tanaka Akira <akr@...17n.org> 2005/02/24

In article <20050224091450P.aamine@loveruby.net>,

[ruby-dev:25734] Re: pthread trouble on sighandler

From: Hidetoshi NAGAI <nagai@...>
Date: 2005-02-21 06:09:19 UTC
List: ruby-dev #25734
永井@知能.九工大です.

From: Yukihiro Matsumoto <matz@ruby-lang.org>
Subject: [ruby-dev:25721] Re: pthread trouble on sighandler
Date: Sat, 19 Feb 2005 10:19:32 +0900
Message-ID: <1108775957.264706.21833.nullmailer@x31.priv.netlab.jp>
> そういうことです。コミットしてくださいますか。

はい,承知しました.
ただ,その後にちょっと手を入れてしまってますので,
添付のもので問題がなければコミットさせていただきます.
追加で手を入れた部分は,

 ・sighandler() 以外の sigbus() 等でも ruby 外の native thread を
   無視するように設定.

 ・ハンドラの登録状態を得る Signal.accept_nativethread?(sig) を追加.
   ただし,「受理可として登録されたか否か」を返しているだけなので,
   本当に複数の native thread のシグナルを扱えるのかどうかは
   登録されたハンドラ次第となる.

という部分です.
ちなみに標準のハンドラ (trap メソッドで登録した場合を含む) では
Signal.accept_nativethread?(sig) ==> false です.

------------------------------------------------------------------------
* signal.c: Standard signal handlers ignore signals on non-Ruby native
  threads. When a handler is entried with ruby_signal() (like as the
  standard signal handlers), the handler for the signal is marked as
  it cannot accept non-Ruby native threads. If a handler can treat all
  signals on all native threads, please use ruby_nativethread_signal()
  to entry it. Signal.accept_nativethreads?(sig) returns current 
  status for `sig'. If a handler for a signal `sig' is entried with
  ruby_nativethread_signal(), Signal.accept_nativethreads?(sig)
  returns `true'. The status `false' means either of `cannot accept'
  or `ignore' non-Ruby native threads. Note that the status doesn't
  guarantee the handler's ability.
------------------------------------------------------------------------

Index: intern.h
===================================================================
RCS file: /var/cvs/src/ruby/intern.h,v
retrieving revision 1.163
diff -u -r1.163 intern.h
--- intern.h	16 Dec 2004 15:01:49 -0000	1.163
+++ intern.h	21 Feb 2005 05:56:38 -0000
@@ -400,6 +400,11 @@
 #ifdef POSIX_SIGNAL
 #define posix_signal ruby_posix_signal
 void posix_signal _((int, RETSIGTYPE (*)(int)));
+#ifdef HAVE_NATIVETHREAD
+#define posix_nativethread_signal ruby_posix_nativethread_signal
+void posix_nativethread_signal _((int, RETSIGTYPE (*)(int)));
+VALUE rb_accept_nativethreads_p _((VALUE, VALUE));
+#endif
 #endif
 void rb_trap_exit _((void));
 void rb_trap_exec _((void));
Index: signal.c
===================================================================
RCS file: /var/cvs/src/ruby/signal.c,v
retrieving revision 1.55
diff -u -r1.55 signal.c
--- signal.c	30 Nov 2004 17:28:16 -0000	1.55
+++ signal.c	21 Feb 2005 05:56:38 -0000
@@ -303,6 +303,7 @@
     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;
@@ -320,6 +321,55 @@
 #endif /* MACOS_UNUSE_SIGNAL */
 }
 
+VALUE
+rb_accept_nativethreads_p(obj, sig)
+    VALUE obj;
+    VALUE sig;
+{
+#ifndef HAVE_NATIVETHREAD
+    return Qfalse;
+#else
+    int signum = -1;
+    char *s;
+
+    switch (TYPE(sig)) {
+      case T_FIXNUM:
+	signum = FIX2INT(sig);
+	break;
+
+      case T_SYMBOL:
+	s = rb_id2name(SYM2ID(sig));
+	if (!s) rb_raise(rb_eArgError, "bad signal");
+	goto str_signal;
+
+      case T_STRING:
+	s = RSTRING(sig)->ptr;
+
+      str_signal:
+	if (strncmp("SIG", s, 3) == 0)
+	    s += 3;
+	signum = signm2signo(s);
+	if (signum == 0 && strcmp(s, "EXIT") != 0)
+	    rb_raise(rb_eArgError, "unsupported signal SIG%s", s);
+    }
+
+    if (signum < 0 || signum > NSIG) {
+	rb_raise(rb_eArgError, "invalid signal number (%d)", signum);
+    }
+#if defined(HAVE_SETITIMER)
+    if (signum == SIGVTALRM) {
+	rb_raise(rb_eArgError, "SIGVTALRM reserved for Thread; cannot set handler");
+    }
+#endif
+
+    if (rb_trap_accept_nativethreads[signum]) {
+        return Qtrue;
+    } else {
+        return Qfalse;
+    }
+#endif
+}
+
 #ifdef __dietlibc__
 #define sighandler_t sh_t
 #endif
@@ -334,6 +384,8 @@
 {
     struct sigaction sigact, old;
 
+    rb_trap_accept_nativethreads[signum] = 0;
+
     sigact.sa_handler = handler;
     sigemptyset(&sigact.sa_mask);
     sigact.sa_flags = 0;
@@ -360,8 +412,30 @@
 {
     ruby_signal(signum, handler);
 }
-#else
-#define ruby_signal(sig,handler) signal((sig),(handler))
+
+#ifdef HAVE_NATIVETHREAD
+static sighandler_t
+ruby_nativethread_signal(signum, handler)
+    int signum;
+    sighandler_t handler;
+{
+    ruby_signal(signum, handler);
+    rb_trap_accept_nativethreads[signum] = 1;
+}
+
+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
+#define ruby_nativethread_signal(sig,handler) {signal((sig),(handler));rb_trap_accept_nativethreads[sig] = 1;}
+#endif
 #endif
 
 static void signal_exec _((int sig));
@@ -408,13 +482,23 @@
 #else
 #define IN_MAIN_CONTEXT(f, a) f(a)
 #endif
-
     if (sig >= NSIG) {
 	rb_bug("trap_handler: Bad signal %d", sig);
     }
 
+#ifdef HAVE_NATIVETHREAD
+    if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {
+        /* ignore signals on non-Ruby native thread */
+        return;
+    }
+#endif
+
 #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
-    ruby_signal(sig, sighandler);
+    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)) {
@@ -433,6 +517,13 @@
 sigbus(sig)
     int sig;
 {
+#ifdef HAVE_NATIVETHREAD
+    if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {
+        /* ignore signals on non-Ruby native thread */
+        return;
+    }
+#endif
+
     rb_bug("Bus Error");
 }
 #endif
@@ -443,6 +534,13 @@
 sigsegv(sig)
     int sig;
 {
+#ifdef HAVE_NATIVETHREAD
+    if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {
+        /* ignore signals on non-Ruby native thread */
+        return;
+    }
+#endif
+
     rb_bug("Segmentation fault");
 }
 #endif
@@ -508,6 +606,13 @@
 sigexit(sig)
     int sig;
 {
+#ifdef HAVE_NATIVETHREAD
+    if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {
+        /* ignore signals on non-Ruby native thread */
+        return;
+    }
+#endif
+
     rb_exit(0);
 }
 
@@ -771,6 +876,27 @@
     }
 }
 
+#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
+
 static void
 init_sigchld(sig)
     int sig;
@@ -859,6 +985,8 @@
     rb_define_global_function("trap", sig_trap, -1);
     rb_define_module_function(mSignal, "trap", sig_trap, -1);
     rb_define_module_function(mSignal, "list", sig_list, 0);
+    rb_define_module_function(mSignal, "accept_nativethreads?", 
+                              rb_accept_nativethreads_p, 1);
 
     install_sighandler(SIGINT, sighandler);
 #ifdef SIGHUP


-- 
                                       永井 秀利 (九工大 知能情報)
                                           nagai@ai.kyutech.ac.jp

In This Thread