@@ -45,7 +45,7 @@ def rubybin
45
45
RUBYLIB = ENV [ "RUBYLIB" ]
46
46
47
47
class << self
48
- attr_accessor :subprocess_timeout_scale
48
+ attr_accessor :timeout_scale
49
49
attr_reader :original_internal_encoding , :original_external_encoding ,
50
50
:original_verbose
51
51
@@ -57,22 +57,63 @@ def capture_global_values
57
57
end
58
58
59
59
def apply_timeout_scale ( t )
60
- if scale = EnvUtil . subprocess_timeout_scale
60
+ if scale = EnvUtil . timeout_scale
61
61
t * scale
62
62
else
63
63
t
64
64
end
65
65
end
66
66
module_function :apply_timeout_scale
67
67
68
+ def timeout ( sec , klass = nil , message = nil , &blk )
69
+ return yield ( sec ) if sec == nil or sec . zero?
70
+ sec = apply_timeout_scale ( sec )
71
+ Timeout . timeout ( sec , klass , message , &blk )
72
+ end
73
+ module_function :timeout
74
+
75
+ def terminate ( pid , signal = :TERM , pgroup = nil , reprieve = 1 )
76
+ reprieve = apply_timeout_scale ( reprieve ) if reprieve
77
+
78
+ signals = Array ( signal ) . select do |sig |
79
+ DEFAULT_SIGNALS [ sig . to_s ] or
80
+ DEFAULT_SIGNALS [ Signal . signame ( sig ) ] rescue false
81
+ end
82
+ signals |= [ :ABRT , :KILL ]
83
+ case pgroup
84
+ when 0 , true
85
+ pgroup = -pid
86
+ when nil , false
87
+ pgroup = pid
88
+ end
89
+ while signal = signals . shift
90
+ begin
91
+ Process . kill signal , pgroup
92
+ rescue Errno ::EINVAL
93
+ next
94
+ rescue Errno ::ESRCH
95
+ break
96
+ end
97
+ if signals . empty? or !reprieve
98
+ Process . wait ( pid )
99
+ else
100
+ begin
101
+ Timeout . timeout ( reprieve ) { Process . wait ( pid ) }
102
+ rescue Timeout ::Error
103
+ end
104
+ end
105
+ end
106
+ $?
107
+ end
108
+ module_function :terminate
109
+
68
110
def invoke_ruby ( args , stdin_data = "" , capture_stdout = false , capture_stderr = false ,
69
111
encoding : nil , timeout : 10 , reprieve : 1 , timeout_error : Timeout ::Error ,
70
112
stdout_filter : nil , stderr_filter : nil ,
71
113
signal : :TERM ,
72
114
rubybin : EnvUtil . rubybin , precommand : nil ,
73
115
**opt )
74
116
timeout = apply_timeout_scale ( timeout )
75
- reprieve = apply_timeout_scale ( reprieve ) if reprieve
76
117
77
118
in_c , in_p = IO . pipe
78
119
out_p , out_c = IO . pipe if capture_stdout
@@ -108,35 +149,7 @@ def invoke_ruby(args, stdin_data = "", capture_stdout = false, capture_stderr =
108
149
if ( !th_stdout || th_stdout . join ( timeout ) ) && ( !th_stderr || th_stderr . join ( timeout ) )
109
150
timeout_error = nil
110
151
else
111
- signals = Array ( signal ) . select do |sig |
112
- DEFAULT_SIGNALS [ sig . to_s ] or
113
- DEFAULT_SIGNALS [ Signal . signame ( sig ) ] rescue false
114
- end
115
- signals |= [ :ABRT , :KILL ]
116
- case pgroup = opt [ :pgroup ]
117
- when 0 , true
118
- pgroup = -pid
119
- when nil , false
120
- pgroup = pid
121
- end
122
- while signal = signals . shift
123
- begin
124
- Process . kill signal , pgroup
125
- rescue Errno ::EINVAL
126
- next
127
- rescue Errno ::ESRCH
128
- break
129
- end
130
- if signals . empty? or !reprieve
131
- Process . wait ( pid )
132
- else
133
- begin
134
- Timeout . timeout ( reprieve ) { Process . wait ( pid ) }
135
- rescue Timeout ::Error
136
- end
137
- end
138
- end
139
- status = $?
152
+ status = terminate ( pid , signal , opt [ :pgroup ] , reprieve )
140
153
end
141
154
stdout = th_stdout . value if capture_stdout
142
155
stderr = th_stderr . value if capture_stderr && capture_stderr != :merge_to_stdout
0 commit comments