ext/stackprof/stackprof.c in stackprof-0.2.22 vs ext/stackprof/stackprof.c in stackprof-0.2.23

- old
+ new

@@ -123,10 +123,12 @@ int buffer_count; sample_time_t buffer_time; VALUE frames_buffer[BUF_SIZE]; int lines_buffer[BUF_SIZE]; + + pthread_t target_thread; } _stackprof; static VALUE sym_object, sym_wall, sym_cpu, sym_custom, sym_name, sym_file, sym_line; static VALUE sym_samples, sym_total_samples, sym_missed_samples, sym_edges, sym_lines; static VALUE sym_version, sym_mode, sym_interval, sym_raw, sym_metadata, sym_frames, sym_ignore_gc, sym_out; @@ -217,10 +219,11 @@ _stackprof.mode = mode; _stackprof.interval = interval; _stackprof.ignore_gc = ignore_gc; _stackprof.metadata = metadata; _stackprof.out = out; + _stackprof.target_thread = pthread_self(); if (raw) { capture_timestamp(&_stackprof.last_sample_at); } @@ -719,10 +722,25 @@ static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; _stackprof.overall_signals++; if (!_stackprof.running) return; - if (!ruby_native_thread_p()) return; + + if (_stackprof.mode == sym_wall) { + // In "wall" mode, the SIGALRM signal will arrive at an arbitrary thread. + // In order to provide more useful results, especially under threaded web + // servers, we want to forward this signal to the original thread + // StackProf was started from. + // According to POSIX.1-2008 TC1 pthread_kill and pthread_self should be + // async-signal-safe. + if (pthread_self() != _stackprof.target_thread) { + pthread_kill(_stackprof.target_thread, sig); + return; + } + } else { + if (!ruby_native_thread_p()) return; + } + if (pthread_mutex_trylock(&lock)) return; if (!_stackprof.ignore_gc && rb_during_gc()) { VALUE mode = rb_gc_latest_gc_info(sym_state); if (mode == sym_marking) {