SystemTimer 1.0 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog CHANGED
@@ -1,3 +1,16 @@
1
+ === 1.1.0 / 2008-11-05
2
+
3
+ * New implementation supporting concurrent timers, i.e. :
4
+
5
+ (1..10).each do
6
+ Thread.new do
7
+ SystemTimer.timeout_after(5) do
8
+ sleep 60
9
+ puts "hi there!"
10
+ end
11
+ end
12
+ end
13
+
1
14
  === 1.0.0 / 2008-02-27
2
15
 
3
16
  * Initial Release
data/README CHANGED
@@ -5,6 +5,11 @@ solution to Ruby processes which hang beyond the time limit when accessing
5
5
  external resources. This is useful when timeout.rb, which relies on green
6
6
  threads, does not work consistently.
7
7
 
8
+ More background on:
9
+
10
+ * http://ph7spot.com/articles/system_timer
11
+ * http://davidvollbracht.com/2008/6/2/30-days-of-teach-day-1-systemtimer
12
+
8
13
  == Usage
9
14
 
10
15
  require 'systemtimer'
@@ -58,6 +63,8 @@ in particular MySQL.
58
63
  This implementation is not intended to be drop-in replacement to
59
64
  timeout.rb, just a way to wrap sensitive call to system resources.
60
65
 
66
+ You can find more details on SystemTimer and how to use it
67
+ at http://ph7spot.com/articles/system_timer
61
68
 
62
69
  == License
63
70
 
File without changes
@@ -1,7 +1,14 @@
1
+ /*
2
+ * SystemTimer native implementation relying on ITIMER_REAL
3
+ *
4
+ * Copyright 2008 David Vollbracht & Philippe Hanrigou
5
+ */
6
+
1
7
  #include "ruby.h"
2
8
  #include "rubysig.h"
3
9
  #include <signal.h>
4
10
  #include <errno.h>
11
+ #include <stdarg.h>
5
12
 
6
13
  #define DISPLAY_ERRNO 1
7
14
  #define DO_NOT_DISPLAY_ERRNO 0
@@ -11,103 +18,151 @@ sigset_t original_mask;
11
18
  sigset_t sigalarm_mask;
12
19
  struct sigaction original_signal_handler;
13
20
  struct itimerval original_timer_interval;
21
+ static int debug_enabled = 0;
14
22
 
15
23
  static void clear_pending_sigalrm_for_ruby_threads();
16
- static void log_debug(char*);
17
- static void log_error(char*, int);
18
24
  static void install_ruby_sigalrm_handler(VALUE);
19
25
  static void restore_original_ruby_sigalrm_handler(VALUE);
20
26
  static void restore_original_sigalrm_mask_when_blocked();
21
27
  static void restore_original_timer_interval();
28
+ static void set_itimerval_with_minimum_1s_interval(struct itimerval *, int);
22
29
  static void set_itimerval(struct itimerval *, int);
30
+ static void restore_sigalrm_mask(sigset_t *previous_mask);
31
+ static void log_debug(char*, ...);
32
+ static void log_error(char*, int);
23
33
 
24
- static int debug_enabled = 0;
25
34
 
26
- static VALUE install_timer(VALUE self, VALUE seconds)
35
+ static VALUE install_first_timer_and_save_original_configuration(VALUE self, VALUE seconds)
27
36
  {
28
- struct itimerval timer_interval;
29
-
30
- /*
31
- * Block SIG_ALRM for safe processing of SIG_ALRM configuration and save mask.
32
- */
33
- if (0 != sigprocmask(SIG_BLOCK, &sigalarm_mask, &original_mask)) {
34
- log_error("install_timer: Could not block SIG_ALRM", DISPLAY_ERRNO);
35
- return Qnil;
36
- }
37
- clear_pending_sigalrm_for_ruby_threads();
38
- log_debug("install_timer: Succesfully blocked SIG_ALRM at O.S. level");
37
+ struct itimerval timer_interval;
38
+
39
+ if (debug_enabled) {
40
+ log_debug("[install_first_timer] %d s\n", NUM2INT(seconds));
41
+ }
42
+
43
+ /*
44
+ * Block SIG_ALRM for safe processing of SIG_ALRM configuration and save mask.
45
+ */
46
+ if (0 != sigprocmask(SIG_BLOCK, &sigalarm_mask, &original_mask)) {
47
+ log_error("[install_first_timer] Could not block SIG_ALRM\n", DISPLAY_ERRNO);
48
+ return Qnil;
49
+ }
50
+ clear_pending_sigalrm_for_ruby_threads();
51
+ log_debug("[install_first_timer] Successfully blocked SIG_ALRM at O.S. level\n");
39
52
 
40
- /*
41
- * Save previous signal handler.
42
- */
43
- original_signal_handler.sa_handler = NULL;
44
- if (0 != sigaction(SIGALRM, NULL, &original_signal_handler)) {
45
- log_error("install_timer: Could not save existing handler for SIG_ALRM", DISPLAY_ERRNO);
46
- restore_original_sigalrm_mask_when_blocked();
47
- return Qnil;
48
- }
49
- log_debug("install_timer: Succesfully saved existing SIG_ALRM handler");
50
-
51
- /*
52
- * Install Ruby Level SIG_ALRM handler
53
- */
54
- install_ruby_sigalrm_handler(self);
55
-
56
- /*
57
- * Set new real time interval timer and save the original if any.
58
- */
59
- set_itimerval(&original_timer_interval, 0);
60
- set_itimerval(&timer_interval, NUM2INT(seconds));
61
- if (0 != setitimer(ITIMER_REAL, &timer_interval, &original_timer_interval)) {
62
- log_error("install_timer: Could not install our own timer, timeout will not work", DISPLAY_ERRNO);
63
- restore_original_ruby_sigalrm_handler(self);
64
- restore_original_sigalrm_mask_when_blocked();
65
- return Qnil;
66
- }
67
- log_debug("install_timer: Successfully installed timer");
68
-
69
- /*
70
- * Unblock SIG_ALRM
71
- */
72
- if (0 != sigprocmask(SIG_UNBLOCK, &sigalarm_mask, NULL)) {
73
- log_error("install_timer: Could not unblock SIG_ALRM, timeout will not work", DISPLAY_ERRNO);
74
- restore_original_timer_interval();
75
- restore_original_ruby_sigalrm_handler(self);
76
- restore_original_sigalrm_mask_when_blocked();
77
- }
78
- log_debug("install_timer: Succesfully unblocked SIG_ALRM.");
79
-
80
- return Qnil;
81
- }
82
-
83
- static VALUE cleanup_timer(VALUE self, VALUE seconds)
53
+ /*
54
+ * Save previous signal handler.
55
+ */
56
+ log_debug("[install_first_timer] Saving original system handler\n");
57
+ original_signal_handler.sa_handler = NULL;
58
+ if (0 != sigaction(SIGALRM, NULL, &original_signal_handler)) {
59
+ log_error("[install_first_timer] Could not save existing handler for SIG_ALRM\n", DISPLAY_ERRNO);
60
+ restore_original_sigalrm_mask_when_blocked();
61
+ return Qnil;
62
+ }
63
+ log_debug("[install_first_timer] Successfully saved existing SIG_ALRM handler\n");
64
+
65
+ /*
66
+ * Install Ruby Level SIG_ALRM handler
67
+ */
68
+ install_ruby_sigalrm_handler(self);
69
+
70
+ /*
71
+ * Save original real time interval timer and aet new real time interval timer.
72
+ */
73
+ set_itimerval(&original_timer_interval, 0);
74
+ set_itimerval_with_minimum_1s_interval(&timer_interval, seconds);
75
+ if (0 != setitimer(ITIMER_REAL, &timer_interval, &original_timer_interval)) {
76
+ log_error("[install_first_timer] Could not install our own timer, timeout will not work", DISPLAY_ERRNO);
77
+ restore_original_ruby_sigalrm_handler(self);
78
+ restore_original_sigalrm_mask_when_blocked();
79
+ return Qnil;
80
+ }
81
+ log_debug("[install_first_timer] Successfully installed timer (%ds)\n", timer_interval.it_value.tv_sec);
82
+
83
+ /*
84
+ * Unblock SIG_ALRM
85
+ */
86
+ if (0 != sigprocmask(SIG_UNBLOCK, &sigalarm_mask, NULL)) {
87
+ log_error("[install_first_timer] Could not unblock SIG_ALRM, timeout will not work", DISPLAY_ERRNO);
88
+ restore_original_timer_interval();
89
+ restore_original_ruby_sigalrm_handler(self);
90
+ restore_original_sigalrm_mask_when_blocked();
91
+ }
92
+ log_debug("[install_first_timer] Successfully unblocked SIG_ALRM.\n");
93
+
94
+ return Qnil;
95
+ }
96
+
97
+ static VALUE install_next_timer(VALUE self, VALUE seconds)
84
98
  {
85
- /*
86
- * Block SIG_ALRM for safe processing of SIG_ALRM configuration.
87
- */
88
- if (0 != sigprocmask(SIG_BLOCK, &sigalarm_mask, NULL)) {
89
- log_error("cleanup_timer: Could not block SIG_ALRM", errno);
90
- }
91
- clear_pending_sigalrm_for_ruby_threads();
92
- log_debug("cleanup_timer: Blocked SIG_ALRM");
93
-
94
- /*
95
- * Install Ruby Level SIG_ALRM handler
96
- */
97
- restore_original_ruby_sigalrm_handler(self);
99
+ struct itimerval timer_interval;
100
+ sigset_t previous_sigalarm_mask;
101
+
102
+ if (debug_enabled) {
103
+ log_debug("[install_next_timer] %ds\n", NUM2INT(seconds));
104
+ }
105
+
106
+ /*
107
+ * Block SIG_ALRM for safe processing of SIG_ALRM configuration and save mask.
108
+ */
109
+ if (0 != sigprocmask(SIG_BLOCK, &sigalarm_mask, &previous_sigalarm_mask)) {
110
+ log_error("[install_next_timer] Could not block SIG_ALRM\n", DISPLAY_ERRNO);
111
+ return Qnil;
112
+ }
113
+ clear_pending_sigalrm_for_ruby_threads();
114
+ log_debug("[install_next_timer] Successfully blocked SIG_ALRM at O.S. level\n");
98
115
 
116
+ /*
117
+ * Set new real time interval timer.
118
+ */
119
+ set_itimerval_with_minimum_1s_interval(&timer_interval, seconds);
120
+ if (0 != setitimer(ITIMER_REAL, &timer_interval, NULL)) {
121
+ log_error("[install_next_timer] Could not install our own timer, timeout will not work", DISPLAY_ERRNO);
122
+ restore_sigalrm_mask(&previous_sigalarm_mask);
123
+ return Qnil;
124
+ }
125
+ log_debug("[install_next_timer] Successfully installed timer (%ds)\n", timer_interval.it_value.tv_sec);
126
+
127
+ /*
128
+ * Unblock SIG_ALRM
129
+ */
130
+ if (0 != sigprocmask(SIG_UNBLOCK, &sigalarm_mask, NULL)) {
131
+ log_error("[install_next_timer] Could not unblock SIG_ALRM, timeout will not work", DISPLAY_ERRNO);
132
+ restore_sigalrm_mask(&previous_sigalarm_mask);
133
+ }
134
+ log_debug("[install_next_timer] Successfully unblocked SIG_ALRM.\n");
135
+
136
+ return Qnil;
137
+ }
138
+
139
+ static VALUE restore_original_configuration(VALUE self)
140
+ {
141
+ /*
142
+ * Block SIG_ALRM for safe processing of SIG_ALRM configuration.
143
+ */
144
+ if (0 != sigprocmask(SIG_BLOCK, &sigalarm_mask, NULL)) {
145
+ log_error("restore_original_configuration: Could not block SIG_ALRM", errno);
146
+ }
147
+ clear_pending_sigalrm_for_ruby_threads();
148
+ log_debug("[restore_original_configuration] Blocked SIG_ALRM\n");
149
+
150
+ /*
151
+ * Install Ruby Level SIG_ALRM handler
152
+ */
153
+ restore_original_ruby_sigalrm_handler(self);
99
154
 
100
- if (original_signal_handler.sa_handler == NULL) {
101
- log_error("cleanup_timer: Previous SIG_ALRM handler not initialized!", DO_NOT_DISPLAY_ERRNO);
102
- } else if (0 == sigaction(SIGALRM, &original_signal_handler, NULL)) {
103
- log_debug("cleanup_timer: Succesfully restored previous handler for SIG_ALRM");
104
- } else {
105
- log_error("cleanup_timer: Could not restore previous handler for SIG_ALRM", DISPLAY_ERRNO);
106
- }
107
- original_signal_handler.sa_handler = NULL;
155
+ if (original_signal_handler.sa_handler == NULL) {
156
+ log_error("[restore_original_configuration] Previous SIG_ALRM handler not initialized!", DO_NOT_DISPLAY_ERRNO);
157
+ } else if (0 == sigaction(SIGALRM, &original_signal_handler, NULL)) {
158
+ log_debug("[restore_original_configuration] Successfully restored previous handler for SIG_ALRM\n");
159
+ } else {
160
+ log_error("[restore_original_configuration] Could not restore previous handler for SIG_ALRM", DISPLAY_ERRNO);
161
+ }
162
+ original_signal_handler.sa_handler = NULL;
108
163
 
109
- restore_original_timer_interval();
110
- restore_original_sigalrm_mask_when_blocked();
164
+ restore_original_timer_interval();
165
+ restore_original_sigalrm_mask_when_blocked();
111
166
  }
112
167
 
113
168
  /*
@@ -119,61 +174,70 @@ static VALUE cleanup_timer(VALUE self, VALUE seconds)
119
174
  *
120
175
  */
121
176
  static void restore_original_timer_interval() {
122
- if (0 != setitimer (ITIMER_REAL, &original_timer_interval, NULL)) {
123
- log_error("install_timer: Could not restore original timer", DISPLAY_ERRNO);
124
- }
125
- log_debug("install_timer: Successfully restored timer");
177
+ if (0 != setitimer(ITIMER_REAL, &original_timer_interval, NULL)) {
178
+ log_error("[restore_original_configuration] Could not restore original timer", DISPLAY_ERRNO);
179
+ }
180
+ log_debug("[restore_original_configuration] Successfully restored original timer\n");
181
+ }
182
+
183
+ static void restore_sigalrm_mask(sigset_t *previous_mask)
184
+ {
185
+ if (!sigismember(previous_mask, SIGALRM)) {
186
+ sigprocmask(SIG_UNBLOCK, &sigalarm_mask, NULL);
187
+ log_debug("[restore_sigalrm_mask] Unblocked SIG_ALRM\n");
188
+ } else {
189
+ log_debug("[restore_sigalrm_mask] No Need to unblock SIG_ALRM\n");
190
+ }
126
191
  }
127
192
 
128
193
  static void restore_original_sigalrm_mask_when_blocked()
129
194
  {
130
- if (!sigismember(&original_mask, SIGALRM)) {
131
- sigprocmask(SIG_UNBLOCK, &sigalarm_mask, NULL);
132
- log_debug("cleanup_timer: Unblocked SIG_ALRM");
133
- } else {
134
- log_debug("cleanup_timer: No Need to unblock SIG_ALRM");
135
- }
195
+ restore_sigalrm_mask(&original_mask);
136
196
  }
137
197
 
138
198
  static void install_ruby_sigalrm_handler(VALUE self) {
139
- rb_thread_critical = 1;
140
- rb_funcall(self, rb_intern("install_ruby_sigalrm_handler"), 0);
141
- rb_thread_critical = 0;
199
+ rb_thread_critical = 1;
200
+ rb_funcall(self, rb_intern("install_ruby_sigalrm_handler"), 0);
201
+ rb_thread_critical = 0;
142
202
  }
143
203
 
144
204
  static void restore_original_ruby_sigalrm_handler(VALUE self) {
145
- rb_thread_critical = 1;
146
- rb_funcall(self, rb_intern("restore_original_ruby_sigalrm_handler"), 0);
147
- rb_thread_critical = 0;
205
+ rb_thread_critical = 1;
206
+ rb_funcall(self, rb_intern("restore_original_ruby_sigalrm_handler"), 0);
207
+ rb_thread_critical = 0;
148
208
  }
149
209
 
150
210
 
151
211
  static VALUE debug_enabled_p(VALUE self) {
152
- return debug_enabled ? Qtrue : Qfalse;
212
+ return debug_enabled ? Qtrue : Qfalse;
153
213
  }
154
214
 
155
215
  static VALUE enable_debug(VALUE self) {
156
- debug_enabled = 1;
157
- return Qnil;
216
+ debug_enabled = 1;
217
+ return Qnil;
158
218
  }
159
219
 
160
220
  static VALUE disable_debug(VALUE self) {
161
- debug_enabled = 0;
162
- return Qnil;
221
+ debug_enabled = 0;
222
+ return Qnil;
163
223
  }
164
224
 
165
- static void log_debug(char* message)
225
+ static void log_debug(char* message, ...)
166
226
  {
167
- if (0 != debug_enabled) {
168
- printf("%s\n", message);
169
- }
170
- return;
227
+ va_list argp;
228
+
229
+ if (0 != debug_enabled) {
230
+ va_start(argp, message);
231
+ vfprintf(stdout, message, argp);
232
+ va_end(argp);
233
+ }
234
+ return;
171
235
  }
172
236
 
173
237
  static void log_error(char* message, int display_errno)
174
238
  {
175
- fprintf(stderr, "%s: %s\n", message, display_errno ? strerror(errno) : "");
176
- return;
239
+ fprintf(stderr, "%s: %s\n", message, display_errno ? strerror(errno) : "");
240
+ return;
177
241
  }
178
242
 
179
243
  /*
@@ -186,32 +250,45 @@ static void log_error(char* message, int display_errno)
186
250
  */
187
251
  static void clear_pending_sigalrm_for_ruby_threads()
188
252
  {
189
- CHECK_INTS;
190
- log_debug("Succesfully triggered all pending signals at Green Thread level");
253
+ CHECK_INTS;
254
+ log_debug("[native] Successfully triggered all pending signals at Green Thread level\n");
191
255
  }
192
256
 
193
257
  static void init_sigalarm_mask()
194
258
  {
195
- sigemptyset(&sigalarm_mask);
196
- sigaddset(&sigalarm_mask, SIGALRM);
197
- return;
259
+ sigemptyset(&sigalarm_mask);
260
+ sigaddset(&sigalarm_mask, SIGALRM);
261
+ return;
262
+ }
263
+
264
+ static void set_itimerval_with_minimum_1s_interval(struct itimerval *value,
265
+ int seconds) {
266
+
267
+ int sanitized_second_interval;
268
+
269
+ sanitized_second_interval = NUM2INT(seconds);
270
+ if (sanitized_second_interval <= 0 ) {
271
+ sanitized_second_interval = 1;
272
+ }
273
+ set_itimerval(value, sanitized_second_interval);
198
274
  }
199
275
 
200
276
  static void set_itimerval(struct itimerval *value, int seconds) {
201
- value->it_interval.tv_usec = 0;
202
- value->it_interval.tv_sec = 0;
203
- value->it_value.tv_usec = 0;
204
- value->it_value.tv_sec = seconds; // (long int)
205
- return;
277
+ value->it_interval.tv_usec = 0;
278
+ value->it_interval.tv_sec = 0;
279
+ value->it_value.tv_usec = 0;
280
+ value->it_value.tv_sec = seconds; // (long int)
281
+ return;
206
282
  }
207
283
 
208
284
  void Init_system_timer_native()
209
285
  {
210
- init_sigalarm_mask();
211
- rb_cSystemTimer = rb_define_module("SystemTimer");
212
- rb_define_singleton_method(rb_cSystemTimer, "install_timer", install_timer, 1);
213
- rb_define_singleton_method(rb_cSystemTimer, "cleanup_timer", cleanup_timer, 0);
214
- rb_define_singleton_method(rb_cSystemTimer, "debug_enabled?", debug_enabled_p, 0);
215
- rb_define_singleton_method(rb_cSystemTimer, "enable_debug", enable_debug, 0);
216
- rb_define_singleton_method(rb_cSystemTimer, "disable_debug", disable_debug, 0);
286
+ init_sigalarm_mask();
287
+ rb_cSystemTimer = rb_define_module("SystemTimer");
288
+ rb_define_singleton_method(rb_cSystemTimer, "install_first_timer_and_save_original_configuration", install_first_timer_and_save_original_configuration, 1);
289
+ rb_define_singleton_method(rb_cSystemTimer, "install_next_timer", install_next_timer, 1);
290
+ rb_define_singleton_method(rb_cSystemTimer, "restore_original_configuration", restore_original_configuration, 0);
291
+ rb_define_singleton_method(rb_cSystemTimer, "debug_enabled?", debug_enabled_p, 0);
292
+ rb_define_singleton_method(rb_cSystemTimer, "enable_debug", enable_debug, 0);
293
+ rb_define_singleton_method(rb_cSystemTimer, "disable_debug", disable_debug, 0);
217
294
  }
@@ -1,11 +1,21 @@
1
+ # Copyright 2008 David Vollbracht & Philippe Hanrigou
2
+
1
3
  require 'rubygems'
2
4
  require 'timeout'
5
+ require 'forwardable'
6
+ require File.dirname(__FILE__) + '/system_timer/thread_timer'
7
+ require File.dirname(__FILE__) + '/system_timer/concurrent_timer_pool'
3
8
 
4
- # Timer based on underlying SIGALRM system timers, is a
9
+ # Timer based on underlying +ITIMER_REAL+ system timer. It is a
5
10
  # solution to Ruby processes which hang beyond the time limit when accessing
6
11
  # external resources. This is useful when timeout.rb, which relies on green
7
12
  # threads, does not work consistently.
8
13
  #
14
+ # For more information and background check out:
15
+ #
16
+ # * http://ph7spot.com/articles/system_timer
17
+ # * http://davidvollbracht.com/2008/6/2/30-days-of-teach-day-1-systemtimer
18
+ #
9
19
  # == Usage
10
20
  #
11
21
  # require 'systemtimer'
@@ -17,54 +27,79 @@ require 'timeout'
17
27
  #
18
28
  # end
19
29
  #
20
- module SystemTimer
21
- class << self
22
-
23
- # Executes the method's block. If the block execution terminates before
24
- # +seconds+ seconds has passed, it returns true. If not, it terminates
25
- # the execution and raises a +Timeout::Error+.
26
- def timeout_after(seconds)
27
- install_timer(seconds)
28
- return yield
29
- ensure
30
- cleanup_timer
31
- end
30
+ module SystemTimer
32
31
 
33
- # Backward compatibility with timeout.rb
34
- alias timeout timeout_after
32
+ Thread.exclusive do # Avoid race conditions for mutex and pool creation
33
+ @timer_pool = ConcurrentTimerPool.new
34
+ @mutex = Mutex.new
35
+ end
36
+
37
+ class << self
38
+ attr_reader :timer_pool
39
+
40
+ # Executes the method's block. If the block execution terminates before
41
+ # +seconds+ seconds has passed, it returns true. If not, it terminates
42
+ # the execution and raises a +Timeout::Error+.
43
+ def timeout_after(seconds)
44
+ new_timer = nil # just for scope
45
+ @mutex.synchronize do
46
+ new_timer = timer_pool.add_timer seconds
47
+ timer_interval = timer_pool.next_trigger_interval_in_seconds
48
+ debug "==== Install Timer ==== at #{Time.now.to_i}, next interval: #{timer_interval}"
49
+ if timer_pool.first_timer?
50
+ install_first_timer_and_save_original_configuration timer_interval
51
+ else
52
+ install_next_timer timer_interval
53
+ end
54
+ end
55
+ return yield
56
+ ensure
57
+ @mutex.synchronize do
58
+ debug "==== Cleanup Timer ==== at #{Time.now.to_i}, #{new_timer} "
59
+ timer_pool.cancel new_timer
60
+ timer_pool.log_registered_timers if debug_enabled?
61
+ next_interval = timer_pool.next_trigger_interval_in_seconds
62
+ debug "Cleanup Timer : next interval #{next_interval.inspect} "
63
+ if next_interval
64
+ install_next_timer next_interval
65
+ else
66
+ restore_original_configuration
67
+ end
68
+ end
69
+ end
70
+
71
+ # Backward compatibility with timeout.rb
72
+ alias timeout timeout_after
35
73
 
36
74
  protected
37
75
 
38
- def install_ruby_sigalrm_handler #:nodoc:
39
- timed_thread = Thread.current # Ruby signals are always delivered to main thread by default.
76
+ def install_ruby_sigalrm_handler #:nodoc:
40
77
  @original_ruby_sigalrm_handler = trap('SIGALRM') do
41
- log_timeout_received(timed_thread) if SystemTimer.debug_enabled?
42
- timed_thread.raise Timeout::Error.new("time's up!")
43
- end
78
+ @mutex.synchronize do
79
+ # Triggers timers one at a time to ensure more deterministic results
80
+ timer_pool.trigger_next_expired_timer
81
+ end
82
+ end
44
83
  end
45
84
 
46
- def restore_original_ruby_sigalrm_handler #:nodoc:
85
+ def restore_original_ruby_sigalrm_handler #:nodoc:
47
86
  trap('SIGALRM', original_ruby_sigalrm_handler || 'DEFAULT')
48
87
  ensure
49
88
  reset_original_ruby_sigalrm_handler
50
89
  end
51
90
 
52
- def original_ruby_sigalrm_handler #:nodoc:
91
+ def original_ruby_sigalrm_handler #:nodoc:
53
92
  @original_ruby_sigalrm_handler
54
93
  end
55
94
 
56
- def reset_original_ruby_sigalrm_handler #:nodoc:
95
+ def reset_original_ruby_sigalrm_handler #:nodoc:
57
96
  @original_ruby_sigalrm_handler = nil
58
97
  end
59
98
 
60
- def log_timeout_received(timed_thread) #:nodoc:
61
- puts <<-EOS
62
- install_ruby_sigalrm_handler: Got Timeout in #{Thread.current}
63
- Main thread : #{Thread.main}
64
- Timed_thread : #{timed_thread}
65
- All Threads : #{Thread.list.inspect}
66
- EOS
99
+ def debug(message) #:nodoc
100
+ puts message if debug_enabled?
67
101
  end
102
+
68
103
  end
69
104
 
70
105
  end