Bug #4765 » fix-signalmask.patch
| eval.c | ||
|---|---|---|
| 
     	JUMP_TAG(TAG_FATAL); 
   | 
||
| 
         } 
   | 
||
| 
         rb_trap_restore_mask(); 
   | 
||
| 
         if (tag != TAG_FATAL) { 
   | 
||
| 
     	EXEC_EVENT_HOOK(th, RUBY_EVENT_RAISE, th->cfp->self, 0, 0); 
   | 
||
| 
         } 
   | 
||
| eval_intern.h | ||
|---|---|---|
| 
     void rb_thread_terminate_all(void); 
   | 
||
| 
     VALUE rb_vm_top_self(); 
   | 
||
| 
     VALUE rb_vm_cbase(void); 
   | 
||
| 
     void rb_trap_restore_mask(void); 
   | 
||
| 
     #ifndef CharNext		/* defined as CharNext[AW] on Windows. */ 
   | 
||
| 
     #define CharNext(p) ((p) + mblen((p), RUBY_MBCHAR_MAXSIZE)) 
   | 
||
| lib/test/unit/parallel.rb | ||
|---|---|---|
| 
             @@stop_auto_run = true 
   | 
||
| 
             @opts = @options.dup 
   | 
||
| 
             Signal.trap(:INT,"IGNORE") 
   | 
||
| 
             @old_loadpath = [] 
   | 
||
| 
             begin 
   | 
||
| 
               @stdout = increment_io(STDOUT) 
   | 
||
| process.c | ||
|---|---|---|
| 
      * Therefore we have to kill internal threads at once. [ruby-core: 10583] 
   | 
||
| 
      */ 
   | 
||
| 
     #define before_exec() \ 
   | 
||
| 
         (rb_enable_interrupt(), (void)(forked_child ? 0 : (rb_thread_stop_timer_thread(), 1))) 
   | 
||
| 
         ((void)(forked_child ? 0 : (rb_thread_stop_timer_thread(), 1))) 
   | 
||
| 
     #define after_exec() \ 
   | 
||
| 
       (rb_thread_reset_timer_thread(), rb_thread_start_timer_thread(), forked_child = 0, rb_disable_interrupt()) 
   | 
||
| 
         (rb_thread_reset_timer_thread(), rb_thread_start_timer_thread(), forked_child = 0) 
   | 
||
| 
     #define before_fork() before_exec() 
   | 
||
| 
     #define after_fork() (GET_THREAD()->thrown_errinfo = 0, after_exec()) 
   | 
||
| ... | ... | |
| 
     void 
   | 
||
| 
     rb_syswait(rb_pid_t pid) 
   | 
||
| 
     { 
   | 
||
| 
         static int overriding; 
   | 
||
| 
     #ifdef SIGHUP 
   | 
||
| 
         RETSIGTYPE (*hfunc)(int) = 0; 
   | 
||
| 
     #endif 
   | 
||
| 
     #ifdef SIGQUIT 
   | 
||
| 
         RETSIGTYPE (*qfunc)(int) = 0; 
   | 
||
| 
     #endif 
   | 
||
| 
         RETSIGTYPE (*ifunc)(int) = 0; 
   | 
||
| 
         int status; 
   | 
||
| 
         int i, hooked = FALSE; 
   | 
||
| 
         if (!overriding) { 
   | 
||
| 
     #ifdef SIGHUP 
   | 
||
| 
     	hfunc = signal(SIGHUP, SIG_IGN); 
   | 
||
| 
     #endif 
   | 
||
| 
     #ifdef SIGQUIT 
   | 
||
| 
     	qfunc = signal(SIGQUIT, SIG_IGN); 
   | 
||
| 
     #endif 
   | 
||
| 
     	ifunc = signal(SIGINT, SIG_IGN); 
   | 
||
| 
     	overriding = TRUE; 
   | 
||
| 
     	hooked = TRUE; 
   | 
||
| 
         } 
   | 
||
| 
         int i; 
   | 
||
| 
         do { 
   | 
||
| 
     	i = rb_waitpid(pid, &status, 0); 
   | 
||
| 
         } while (i == -1 && errno == EINTR); 
   | 
||
| 
         if (hooked) { 
   | 
||
| 
     #ifdef SIGHUP 
   | 
||
| 
     	signal(SIGHUP, hfunc); 
   | 
||
| 
     #endif 
   | 
||
| 
     #ifdef SIGQUIT 
   | 
||
| 
     	signal(SIGQUIT, qfunc); 
   | 
||
| 
     #endif 
   | 
||
| 
     	signal(SIGINT, ifunc); 
   | 
||
| 
     	overriding = FALSE; 
   | 
||
| 
         } 
   | 
||
| 
     } 
   | 
||
| 
     static VALUE 
   | 
||
| signal.c | ||
|---|---|---|
| 
     void 
   | 
||
| 
     ruby_default_signal(int sig) 
   | 
||
| 
     { 
   | 
||
| 
         sigset_t sigmask; 
   | 
||
| 
         sigemptyset(&sigmask); 
   | 
||
| 
         sigaddset(&sigmask, sig); 
   | 
||
| 
         pthread_sigmask(SIG_UNBLOCK, &sigmask, NULL); 
   | 
||
| 
         signal(sig, SIG_DFL); 
   | 
||
| 
         raise(sig); 
   | 
||
| 
     } 
   | 
||
| ... | ... | |
| 
         return signal_buff.size; 
   | 
||
| 
     } 
   | 
||
| 
     #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 
   | 
||
| ... | ... | |
| 
     } 
   | 
||
| 
     #endif 
   | 
||
| 
     #ifdef SIGPIPE 
   | 
||
| 
     static RETSIGTYPE 
   | 
||
| 
     sigpipe(int sig) 
   | 
||
| 
     { 
   | 
||
| 
         /* do nothing */ 
   | 
||
| 
     } 
   | 
||
| 
     #endif 
   | 
||
| 
     static void 
   | 
||
| 
     signal_exec(VALUE cmd, int safe, int sig) 
   | 
||
| 
     { 
   | 
||
| ... | ... | |
| 
     #endif 
   | 
||
| 
     #ifdef SIGPIPE 
   | 
||
| 
           case SIGPIPE: 
   | 
||
| 
             func = sigpipe; 
   | 
||
| 
     	func = SIG_IGN; 
   | 
||
| 
             break; 
   | 
||
| 
     #endif 
   | 
||
| 
           default: 
   | 
||
| ... | ... | |
| 
     { 
   | 
||
| 
         /* enable interrupt */ 
   | 
||
| 
         pthread_sigmask(SIG_SETMASK, &arg->mask, NULL); 
   | 
||
| 
         trap_last_mask = arg->mask; 
   | 
||
| 
         return 0; 
   | 
||
| 
     } 
   | 
||
| 
     #endif 
   | 
||
| 
     void 
   | 
||
| 
     rb_trap_restore_mask(void) 
   | 
||
| 
     { 
   | 
||
| 
     #if USE_TRAP_MASK 
   | 
||
| 
         pthread_sigmask(SIG_SETMASK, &trap_last_mask, NULL); 
   | 
||
| 
     #endif 
   | 
||
| 
     } 
   | 
||
| 
     /* 
   | 
||
| 
      * call-seq: 
   | 
||
| 
      *   Signal.trap( signal, command ) -> obj 
   | 
||
| ... | ... | |
| 
     #if USE_TRAP_MASK 
   | 
||
| 
         sigdelset(&mask, sig); 
   | 
||
| 
         pthread_sigmask(SIG_SETMASK, &mask, NULL); 
   | 
||
| 
         trap_last_mask = mask; 
   | 
||
| 
     #endif 
   | 
||
| 
     } 
   | 
||
| 
     #endif 
   | 
||
| ... | ... | |
| 
     #endif 
   | 
||
| 
         } 
   | 
||
| 
     #ifdef SIGPIPE 
   | 
||
| 
         install_sighandler(SIGPIPE, sigpipe); 
   | 
||
| 
         install_sighandler(SIGPIPE, SIG_IGN); 
   | 
||
| 
     #endif 
   | 
||
| 
     #if defined(SIGCLD) 
   | 
||
| ... | ... | |
| 
     #elif defined(SIGCHLD) 
   | 
||
| 
         init_sigchld(SIGCHLD); 
   | 
||
| 
     #endif 
   | 
||
| 
         rb_disable_interrupt(); 
   | 
||
| 
     } 
   | 
||
| thread_pthread.c | ||
|---|---|---|
| 
     { 
   | 
||
| 
         struct timespec timeout_10ms; 
   | 
||
| 
         /* only timer thread recieve signal */ 
   | 
||
| 
         rb_enable_interrupt(); 
   | 
||
| 
         timeout_10ms.tv_sec = 0; 
   | 
||
| 
         timeout_10ms.tv_nsec = 10 * 1000 * 1000; 
   | 
||
| ... | ... | |
| 
     static void 
   | 
||
| 
     rb_thread_create_timer_thread(void) 
   | 
||
| 
     { 
   | 
||
| 
         rb_enable_interrupt(); 
   | 
||
| 
         if (!timer_thread_id) { 
   | 
||
| 
     	pthread_attr_t attr; 
   | 
||
| 
     	int err; 
   | 
||
| ... | ... | |
| 
     	native_cond_wait(&timer_thread_cond, &timer_thread_lock); 
   | 
||
| 
     	native_mutex_unlock(&timer_thread_lock); 
   | 
||
| 
         } 
   | 
||
| 
         rb_disable_interrupt(); /* only timer thread recieve signal */ 
   | 
||
| 
     } 
   | 
||
| 
     static int 
   | 
||
| vm_eval.c | ||
|---|---|---|
| 
     	RB_GC_GUARD(desc); 
   | 
||
| 
     	rb_raise(rb_eArgError, "uncaught throw %s", RSTRING_PTR(desc)); 
   | 
||
| 
         } 
   | 
||
| 
         rb_trap_restore_mask(); 
   | 
||
| 
         th->errinfo = NEW_THROW_OBJECT(tag, 0, TAG_THROW); 
   | 
||
| 
         JUMP_TAG(TAG_THROW); 
   | 
||