Project

General

Profile

Bug #4765 » fix-signalmask.patch

kosaki (Motohiro KOSAKI), 05/23/2011 01:33 AM

View differences:

eval.c
441 441
	JUMP_TAG(TAG_FATAL);
442 442
    }
443 443

  
444
    rb_trap_restore_mask();
445

  
446 444
    if (tag != TAG_FATAL) {
447 445
	EXEC_EVENT_HOOK(th, RUBY_EVENT_RAISE, th->cfp->self, 0, 0);
448 446
    }
eval_intern.h
212 212
void rb_thread_terminate_all(void);
213 213
VALUE rb_vm_top_self();
214 214
VALUE rb_vm_cbase(void);
215
void rb_trap_restore_mask(void);
216 215

  
217 216
#ifndef CharNext		/* defined as CharNext[AW] on Windows. */
218 217
#define CharNext(p) ((p) + mblen((p), RUBY_MBCHAR_MAXSIZE))
lib/test/unit/parallel.rb
74 74
        @@stop_auto_run = true
75 75
        @opts = @options.dup
76 76

  
77
        Signal.trap(:INT,"IGNORE")
78 77
        @old_loadpath = []
79 78
        begin
80 79
          @stdout = increment_io(STDOUT)
process.c
989 989
 * Therefore we have to kill internal threads at once. [ruby-core: 10583]
990 990
 */
991 991
#define before_exec() \
992
    (rb_enable_interrupt(), (void)(forked_child ? 0 : (rb_thread_stop_timer_thread(), 1)))
992
    ((void)(forked_child ? 0 : (rb_thread_stop_timer_thread(), 1)))
993 993
#define after_exec() \
994
  (rb_thread_reset_timer_thread(), rb_thread_start_timer_thread(), forked_child = 0, rb_disable_interrupt())
994
    (rb_thread_reset_timer_thread(), rb_thread_start_timer_thread(), forked_child = 0)
995 995
#define before_fork() before_exec()
996 996
#define after_fork() (GET_THREAD()->thrown_errinfo = 0, after_exec())
997 997

  
......
2915 2915
void
2916 2916
rb_syswait(rb_pid_t pid)
2917 2917
{
2918
    static int overriding;
2919
#ifdef SIGHUP
2920
    RETSIGTYPE (*hfunc)(int) = 0;
2921
#endif
2922
#ifdef SIGQUIT
2923
    RETSIGTYPE (*qfunc)(int) = 0;
2924
#endif
2925
    RETSIGTYPE (*ifunc)(int) = 0;
2926 2918
    int status;
2927
    int i, hooked = FALSE;
2928

  
2929
    if (!overriding) {
2930
#ifdef SIGHUP
2931
	hfunc = signal(SIGHUP, SIG_IGN);
2932
#endif
2933
#ifdef SIGQUIT
2934
	qfunc = signal(SIGQUIT, SIG_IGN);
2935
#endif
2936
	ifunc = signal(SIGINT, SIG_IGN);
2937
	overriding = TRUE;
2938
	hooked = TRUE;
2939
    }
2919
    int i;
2940 2920

  
2941 2921
    do {
2942 2922
	i = rb_waitpid(pid, &status, 0);
2943 2923
    } while (i == -1 && errno == EINTR);
2944

  
2945
    if (hooked) {
2946
#ifdef SIGHUP
2947
	signal(SIGHUP, hfunc);
2948
#endif
2949
#ifdef SIGQUIT
2950
	signal(SIGQUIT, qfunc);
2951
#endif
2952
	signal(SIGINT, ifunc);
2953
	overriding = FALSE;
2954
    }
2955 2924
}
2956 2925

  
2957 2926
static VALUE
signal.c
312 312
void
313 313
ruby_default_signal(int sig)
314 314
{
315
    sigset_t sigmask;
316

  
317
    sigemptyset(&sigmask);
318
    sigaddset(&sigmask, sig);
319
    pthread_sigmask(SIG_UNBLOCK, &sigmask, NULL);
320

  
315 321
    signal(sig, SIG_DFL);
316 322
    raise(sig);
317 323
}
......
535 541
    return signal_buff.size;
536 542
}
537 543

  
538
#if USE_TRAP_MASK
539
# ifdef HAVE_SIGPROCMASK
540
static sigset_t trap_last_mask;
541
# else
542
static int trap_last_mask;
543
# endif
544
#endif
545

  
546 544
#if HAVE_PTHREAD_H
547 545
#include <pthread.h>
548 546
#endif
......
623 621
}
624 622
#endif
625 623

  
626
#ifdef SIGPIPE
627
static RETSIGTYPE
628
sigpipe(int sig)
629
{
630
    /* do nothing */
631
}
632
#endif
633

  
634 624
static void
635 625
signal_exec(VALUE cmd, int safe, int sig)
636 626
{
......
746 736
#endif
747 737
#ifdef SIGPIPE
748 738
      case SIGPIPE:
749
        func = sigpipe;
739
	func = SIG_IGN;
750 740
        break;
751 741
#endif
752 742
      default:
......
893 883
{
894 884
    /* enable interrupt */
895 885
    pthread_sigmask(SIG_SETMASK, &arg->mask, NULL);
896
    trap_last_mask = arg->mask;
897 886
    return 0;
898 887
}
899 888
#endif
900 889

  
901
void
902
rb_trap_restore_mask(void)
903
{
904
#if USE_TRAP_MASK
905
    pthread_sigmask(SIG_SETMASK, &trap_last_mask, NULL);
906
#endif
907
}
908

  
909 890
/*
910 891
 * call-seq:
911 892
 *   Signal.trap( signal, command ) -> obj
......
1038 1019
#if USE_TRAP_MASK
1039 1020
    sigdelset(&mask, sig);
1040 1021
    pthread_sigmask(SIG_SETMASK, &mask, NULL);
1041
    trap_last_mask = mask;
1042 1022
#endif
1043 1023
}
1044 1024
#endif
......
1143 1123
#endif
1144 1124
    }
1145 1125
#ifdef SIGPIPE
1146
    install_sighandler(SIGPIPE, sigpipe);
1126
    install_sighandler(SIGPIPE, SIG_IGN);
1147 1127
#endif
1148 1128

  
1149 1129
#if defined(SIGCLD)
......
1151 1131
#elif defined(SIGCHLD)
1152 1132
    init_sigchld(SIGCHLD);
1153 1133
#endif
1134

  
1135
    rb_disable_interrupt();
1154 1136
}
thread_pthread.c
996 996
{
997 997
    struct timespec timeout_10ms;
998 998

  
999
    /* only timer thread recieve signal */
1000
    rb_enable_interrupt();
1001

  
999 1002
    timeout_10ms.tv_sec = 0;
1000 1003
    timeout_10ms.tv_nsec = 10 * 1000 * 1000;
1001 1004

  
......
1024 1027
static void
1025 1028
rb_thread_create_timer_thread(void)
1026 1029
{
1027
    rb_enable_interrupt();
1028

  
1029 1030
    if (!timer_thread_id) {
1030 1031
	pthread_attr_t attr;
1031 1032
	int err;
......
1046 1047
	native_cond_wait(&timer_thread_cond, &timer_thread_lock);
1047 1048
	native_mutex_unlock(&timer_thread_lock);
1048 1049
    }
1049
    rb_disable_interrupt(); /* only timer thread recieve signal */
1050 1050
}
1051 1051

  
1052 1052
static int
vm_eval.c
1442 1442
	RB_GC_GUARD(desc);
1443 1443
	rb_raise(rb_eArgError, "uncaught throw %s", RSTRING_PTR(desc));
1444 1444
    }
1445
    rb_trap_restore_mask();
1446 1445
    th->errinfo = NEW_THROW_OBJECT(tag, 0, TAG_THROW);
1447 1446

  
1448 1447
    JUMP_TAG(TAG_THROW);