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) {