summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--eval.c12
-rw-r--r--ruby.h8
-rw-r--r--signal.c39
4 files changed, 60 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 92a5908d7e..7bbaf1f951 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Wed Mar 2 16:59:50 2005 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * eval.c (ruby_native_thread_kill): call pthread_kill() to send a
+ signal to ruby's native thread
+
+ * ruby.h: add definition of ruby_native_thread_kill()
+
+ * signal.c (sigsend_to_ruby_thread): send the signal to ruby's
+ native thread ([ruby-dev:25744], [ruby-dev:25754]), and set
+ signal mask to the current native thread
+
Wed Mar 2 16:03:08 2005 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/tcltklib.c: enforce thread-check and exception-handling to
diff --git a/eval.c b/eval.c
index fae1ffce7d..ebb16396c9 100644
--- a/eval.c
+++ b/eval.c
@@ -1238,9 +1238,19 @@ void Init_ext _((void));
#ifdef HAVE_NATIVETHREAD
static rb_nativethread_t ruby_thid;
int
-is_ruby_native_thread() {
+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
NORETURN(static void rb_thread_start_1 _((void)));
diff --git a/ruby.h b/ruby.h
index ed3c3a1591..a5ae0636f9 100644
--- a/ruby.h
+++ b/ruby.h
@@ -694,6 +694,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()
@@ -701,10 +704,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)
} /* extern "C" { */
diff --git a/signal.c b/signal.c
index 63cb18cb49..6bcc723d82 100644
--- a/signal.c
+++ b/signal.c
@@ -436,6 +436,29 @@ signal_exec(sig)
}
}
+static void
+sigsend_to_ruby_thread(sig)
+ int sig;
+{
+#ifdef HAVE_NATIVETHREAD_KILL
+# 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)
@@ -450,9 +473,9 @@ sighandler(sig)
rb_bug("trap_handler: Bad signal %d", sig);
}
-#ifdef HAVE_NATIVETHREAD
+#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)
if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {
- /* ignore signals on non-Ruby native thread */
+ sigsend_to_ruby_thread(sig);
return;
}
#endif
@@ -481,9 +504,9 @@ static RETSIGTYPE
sigbus(sig)
int sig;
{
-#ifdef HAVE_NATIVETHREAD
+#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)
if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {
- /* ignore signals on non-Ruby native thread */
+ sigsend_to_ruby_thread(sig);
return;
}
#endif
@@ -498,9 +521,9 @@ static RETSIGTYPE
sigsegv(sig)
int sig;
{
-#ifdef HAVE_NATIVETHREAD
+#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)
if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {
- /* ignore signals on non-Ruby native thread */
+ sigsend_to_ruby_thread(sig);
return;
}
#endif
@@ -570,9 +593,9 @@ static RETSIGTYPE
sigexit(sig)
int sig;
{
-#ifdef HAVE_NATIVETHREAD
+#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)
if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {
- /* ignore signals on non-Ruby native thread */
+ sigsend_to_ruby_thread(sig);
return;
}
#endif