timeout-interrupt 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +2 -14
- data/README.md +1 -1
- data/Rakefile +3 -40
- data/VERSION +1 -1
- data/lib/timeout_interrupt.rb +141 -19
- data/timeout-interrupt.gemspec +28 -63
- metadata +52 -66
- data/.document +0 -5
- data/Gemfile.lock +0 -50
- data/test/helper.rb +0 -23
- data/test/test_ruby-timeout-interrupt.rb +0 -155
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 5392e2634dba25bda8fc76725212aa44a15d2f4162beb60e10a17ee82e655b11
|
|
4
|
+
data.tar.gz: 07efedfea6f6aa995f6b239b2960d8da07d1845769580ed3853fa60397ea1842
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 734548b8dc8e64227e1efa5dfdbe4b9b95cb86ae47dd0d1aad87ec50575f5706319d50df2c57e362c2517efc35c17797379a37cc4ab283cf8a43ecf3569e65e0
|
|
7
|
+
data.tar.gz: 6b2f7432900414d2b19276251deb5932ade594adb8b39cabba62c17017e49f1052119efff231b625fd5d6c711982ae805fde0812c61163c7c18ead8e62e34836
|
data/.gitignore
ADDED
data/Gemfile
CHANGED
|
@@ -1,14 +1,2 @@
|
|
|
1
|
-
source "
|
|
2
|
-
|
|
3
|
-
gem 'ffi-libc'
|
|
4
|
-
|
|
5
|
-
# Add dependencies to develop your gem here.
|
|
6
|
-
# Include everything needed to run rake, tests, features, etc.
|
|
7
|
-
group :development do
|
|
8
|
-
gem "shoulda"
|
|
9
|
-
gem "yard"
|
|
10
|
-
gem "rdoc"
|
|
11
|
-
gem "bundler"
|
|
12
|
-
gem "jeweler"
|
|
13
|
-
gem "simplecov"
|
|
14
|
-
end
|
|
1
|
+
source "https://rubygems.org"
|
|
2
|
+
gemspec
|
data/README.md
CHANGED
data/Rakefile
CHANGED
|
@@ -1,46 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require 'rubygems'
|
|
4
|
-
require 'bundler'
|
|
5
|
-
begin
|
|
6
|
-
Bundler.setup(:default, :development)
|
|
7
|
-
rescue Bundler::BundlerError => e
|
|
8
|
-
$stderr.puts e.message
|
|
9
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
|
10
|
-
exit e.status_code
|
|
11
|
-
end
|
|
12
|
-
require 'rake'
|
|
13
|
-
|
|
14
|
-
require 'jeweler'
|
|
15
|
-
Jeweler::Tasks.new do |gem|
|
|
16
|
-
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
|
17
|
-
gem.name = "timeout-interrupt"
|
|
18
|
-
gem.homepage = "http://github.com/DenisKnauf/ruby-timeout-interrupt"
|
|
19
|
-
gem.license = "AGPLv3"
|
|
20
|
-
gem.summary = %Q{"Interrupts systemcalls too."}
|
|
21
|
-
gem.description = %Q{Timeout-lib, which interrupts everything, also systemcalls. It uses libc-alarm.}
|
|
22
|
-
gem.email = "Denis.Knauf@gmail.com"
|
|
23
|
-
gem.authors = ["Denis Knauf"]
|
|
24
|
-
# dependencies defined in Gemfile
|
|
25
|
-
end
|
|
26
|
-
Jeweler::RubygemsDotOrgTasks.new
|
|
1
|
+
require "bundler/gem_tasks"
|
|
2
|
+
task :default => :spec
|
|
27
3
|
|
|
28
4
|
require 'rake/testtask'
|
|
29
|
-
Rake::TestTask.new
|
|
5
|
+
Rake::TestTask.new :test do |test|
|
|
30
6
|
test.libs << 'lib' << 'test'
|
|
31
7
|
test.pattern = 'test/**/test_*.rb'
|
|
32
8
|
test.verbose = true
|
|
33
9
|
end
|
|
34
|
-
|
|
35
|
-
#require 'simplecov'
|
|
36
|
-
#Rcov::RcovTask.new do |test|
|
|
37
|
-
#test.libs << 'test'
|
|
38
|
-
#test.pattern = 'test/**/test_*.rb'
|
|
39
|
-
#test.verbose = true
|
|
40
|
-
#test.rcov_opts << '--exclude "gems/*"'
|
|
41
|
-
#end
|
|
42
|
-
|
|
43
|
-
task :default => :test
|
|
44
|
-
|
|
45
|
-
require 'yard'
|
|
46
|
-
YARD::Rake::YardocTask.new
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.3.0
|
data/lib/timeout_interrupt.rb
CHANGED
|
@@ -1,40 +1,93 @@
|
|
|
1
1
|
require 'ffi/libc'
|
|
2
2
|
require 'timeout'
|
|
3
3
|
|
|
4
|
-
module
|
|
5
|
-
|
|
6
|
-
attach_function :alarm, [:uint], :uint unless FFI::LibC.respond_to? :alarm
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
|
|
4
|
+
# Helper module for `TimeoutInterrupt`
|
|
5
|
+
# @see TimeoutInterrupt
|
|
10
6
|
module TimeoutInterruptSingleton
|
|
11
7
|
class <<self
|
|
8
|
+
# Stores all timeouts.
|
|
9
|
+
#
|
|
10
|
+
# @param thread [nil] must be nil! Do not use it yet!
|
|
11
|
+
# @return [Hash< key(Integer): [at(Time), backtrace(Array<String>), exception(Exception)] >]
|
|
12
12
|
def timeouts thread = nil
|
|
13
|
-
@timeouts ||= Hash.new {|h,k| h[k] =
|
|
14
|
-
thread = Thread.current
|
|
13
|
+
@timeouts ||= Hash.new {|h,k| h[k] = {} }
|
|
14
|
+
thread = Thread.current unless thread.kind_of? Thread
|
|
15
15
|
thread ? @timeouts[thread] : @timeouts
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
+
# If there's a timed out timeout, it will raise its exception.
|
|
19
|
+
# Can be used for handling ALRM-signal.
|
|
20
|
+
# It will prepare the next timeout, too.
|
|
21
|
+
#
|
|
22
|
+
# The timeout will not removed from timeouts, because it is timed out, yet.
|
|
23
|
+
# First, if timeout-scope will be exit, it will be removed.
|
|
24
|
+
#
|
|
25
|
+
# @return [nil]
|
|
18
26
|
def alarm_trap sig
|
|
19
|
-
|
|
27
|
+
raise_if_sb_timed_out
|
|
28
|
+
setup
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# There is a timed out timeout? It will raise it!
|
|
32
|
+
# You need not to check it yourself, it will do it for you.
|
|
33
|
+
#
|
|
34
|
+
# @return [nil]
|
|
35
|
+
def raise_if_sb_timed_out
|
|
36
|
+
return if self.timeouts.empty?
|
|
37
|
+
_key, (at, bt, exception) = self.timeouts.min_by {|_key,(at,_bt,_ex)| at }
|
|
20
38
|
return if Time.now < at
|
|
21
39
|
raise exception, 'execution expired', bt
|
|
22
40
|
end
|
|
23
41
|
|
|
42
|
+
# Prepares the next timeout. Sets the trap and the shortest timeout as alarm.
|
|
43
|
+
#
|
|
44
|
+
# @return [nil]
|
|
24
45
|
def setup
|
|
25
46
|
if timeouts.empty?
|
|
26
47
|
Signal.trap( 'ALRM') {}
|
|
27
48
|
FFI::LibC.alarm 0
|
|
28
49
|
else
|
|
29
|
-
|
|
30
|
-
secs = (at - Time.now)
|
|
31
|
-
alarm_trap 14 if 0 > secs
|
|
50
|
+
raise_if_sb_timed_out
|
|
32
51
|
Signal.trap 'ALRM', &method( :alarm_trap)
|
|
33
|
-
|
|
52
|
+
_key, (at, _bt) = timeouts.min_by {|_key,(at,_bt)| at }
|
|
53
|
+
FFI::LibC.alarm (at - Time.now).to_i + 1
|
|
34
54
|
end
|
|
55
|
+
nil
|
|
35
56
|
end
|
|
36
57
|
|
|
37
|
-
|
|
58
|
+
# Creates a timeout and calls your block, which has to finish before timeout occurs.
|
|
59
|
+
#
|
|
60
|
+
# @param seconds [0] No timeout, so block can take any time.
|
|
61
|
+
# @param seconds [Integer] In `seconds` Seconds, it should raise a timeout, if not finished.
|
|
62
|
+
# @param seconds [nil] If this and no block given, it will call {setup} for checking and
|
|
63
|
+
# preparing _next_ known timeout.
|
|
64
|
+
# @param exception [exception] which exception will be raised if timed out?
|
|
65
|
+
# @param exception [nil] `TimeoutInterrupt::Error` will be used to raise.
|
|
66
|
+
# @param block [Proc] Will be called and should finish its work before it timed out.
|
|
67
|
+
# @param block [nil] Nothing will happen, instead it will return a Proc,
|
|
68
|
+
# which can be called with a block to use the timeout.
|
|
69
|
+
# @return If block given, the returned value of your block.
|
|
70
|
+
# Or if not, it will return a Proc, which will expect a Proc if called.
|
|
71
|
+
# This Proc has no arguments and will prepare a timeout, like if you had given a block.
|
|
72
|
+
#
|
|
73
|
+
# You can rescue `Timeout::Error`, instead `TimeoutInterrupt::Error`,
|
|
74
|
+
# it is a subclass of `Timeout::Error`.
|
|
75
|
+
#
|
|
76
|
+
# It will call your given block, which has `seconds` seconds to end.
|
|
77
|
+
# If you want to prepare a timeout, which should be used many times,
|
|
78
|
+
# without giving `seconds` and `exception`, you can omit the block,
|
|
79
|
+
# so, `TimeoutInterruptSingleton#timeout` will return a `Proc`, which want to have the block.
|
|
80
|
+
#
|
|
81
|
+
# There is a problem with scoped timeouts. If you rescue a timeout in an other timeout,
|
|
82
|
+
# it's possible, that the other timeout will never timeout, because both are timed out at once.
|
|
83
|
+
# Than you need to call `TimeoutInterruptSingleton#timeout` without arguments.
|
|
84
|
+
# It will prepare the next timeout or it will raise it directy, if timed out.
|
|
85
|
+
#
|
|
86
|
+
# @see TimeoutInterrupt.timeout
|
|
87
|
+
# @see TimeoutInterrupt#timeout
|
|
88
|
+
# @raise exception
|
|
89
|
+
def timeout seconds = nil, exception = nil, &block
|
|
90
|
+
return yield( seconds) if seconds.nil? || 0 == seconds if block_given?
|
|
38
91
|
return setup if seconds.nil?
|
|
39
92
|
seconds = seconds.to_i
|
|
40
93
|
exception ||= TimeoutInterrupt::Error
|
|
@@ -50,7 +103,7 @@ module TimeoutInterruptSingleton
|
|
|
50
103
|
begin
|
|
51
104
|
self.timeouts[key] = [at, bt, exception]
|
|
52
105
|
setup
|
|
53
|
-
yield
|
|
106
|
+
yield seconds
|
|
54
107
|
ensure
|
|
55
108
|
self.timeouts.delete key
|
|
56
109
|
setup
|
|
@@ -59,15 +112,84 @@ module TimeoutInterruptSingleton
|
|
|
59
112
|
end
|
|
60
113
|
end
|
|
61
114
|
|
|
115
|
+
# Can be included, or used directly.
|
|
116
|
+
# In both cases, it provides {#timeout}.
|
|
117
|
+
#
|
|
118
|
+
# @see TimeoutInterruptSingleton
|
|
62
119
|
module TimeoutInterrupt
|
|
120
|
+
# The {TimeoutInterrupt::Error} is the default exception, which will be raised,
|
|
121
|
+
# if something will time out.
|
|
122
|
+
# Its base-class is {Timeout::Error}, so you can replace {Timeout} by {TimeoutInterrupt} without
|
|
123
|
+
# replacing your `rescue Timeout::Error`, but you can.
|
|
63
124
|
class Error < Timeout::Error
|
|
64
125
|
end
|
|
65
126
|
|
|
66
|
-
|
|
67
|
-
|
|
127
|
+
# Creates a timeout and calls your block, which has to finish before timeout occurs.
|
|
128
|
+
#
|
|
129
|
+
# @param seconds [0] No timeout, so block can take any time.
|
|
130
|
+
# @param seconds [Integer] In `seconds` Seconds, it should raise a timeout, if not finished.
|
|
131
|
+
# @param seconds [nil] If also no block given, everything will be ignored and
|
|
132
|
+
# it will call {setup} for checking and preparing next known timeout.
|
|
133
|
+
# @param exception [Exception] which will be raised if timed out.
|
|
134
|
+
# @param exception [nil] `TimeoutInterrupt::Error` will be used to raise.
|
|
135
|
+
# @param block [Proc] Will be called and should finish its work before it timed out.
|
|
136
|
+
# @param block [nil] Nothing will happen, instead it will return a Proc,
|
|
137
|
+
# which can be called with a block to use the timeout.
|
|
138
|
+
# @return If block given, the returned value of your block.
|
|
139
|
+
# Or if not, it will return a Proc, which will expect a Proc if called.
|
|
140
|
+
# This Proc has no arguments and will prepare a timeout, like if you had given a block.
|
|
141
|
+
#
|
|
142
|
+
# You can rescue `Timeout::Error`, instead `TimeoutInterrupt::Error`, it will work too.
|
|
143
|
+
#
|
|
144
|
+
# It will call your given block, which has `seconds` seconds to end.
|
|
145
|
+
# If you want to prepare a timeout, which should be used many times,
|
|
146
|
+
# without giving `seconds` and `exception`, you can omit the block,
|
|
147
|
+
# so, `TimeoutInterruptSingleton#timeout` will return a `Proc`, which want to have the block.
|
|
148
|
+
#
|
|
149
|
+
# There is a problem with scoped timeouts. If you rescue a timeout in an other timeout,
|
|
150
|
+
# it's possible, that the other timeout will never timeout, because both are timed out at once.
|
|
151
|
+
# Than you need to call `TimeoutInterruptSingleton#timeout` without arguments.
|
|
152
|
+
# It will prepare the next timeout or it will raise it directy, if timed out.
|
|
153
|
+
#
|
|
154
|
+
# @see TimeoutInterrupt#timeout
|
|
155
|
+
# @see TimeoutInterruptSingleton.timeout
|
|
156
|
+
# @raise exception
|
|
157
|
+
def self.timeout seconds = nil, exception = nil, &block
|
|
158
|
+
TimeoutInterruptSingleton.timeout seconds, exception, &block
|
|
68
159
|
end
|
|
69
160
|
|
|
70
|
-
|
|
71
|
-
|
|
161
|
+
# Creates a timeout and calls your block, which has to finish before timeout occurs.
|
|
162
|
+
#
|
|
163
|
+
# @param seconds [0] No timeout, so block can take any time.
|
|
164
|
+
# @param seconds [Integer] In `seconds` Seconds, it should raise a timeout, if not finished.
|
|
165
|
+
# @param seconds [nil] If also no block given, everything will be ignored and
|
|
166
|
+
# it will call {setup} for checking and preparing next known timeout.
|
|
167
|
+
# @param exception [Exception] which will be raised if timed out.
|
|
168
|
+
# @param exception [nil] `TimeoutInterrupt::Error` will be used to raise.
|
|
169
|
+
# @param block [Proc] Will be called and should finish its work before it timed out.
|
|
170
|
+
# @param block [nil] Nothing will happen, instead it will return a Proc,
|
|
171
|
+
# which can be called with a block to use the timeout.
|
|
172
|
+
# @return If block given, the returned value of your block.
|
|
173
|
+
# Or if not, it will return a Proc, which will expect a Proc if called.
|
|
174
|
+
# This Proc has no arguments and will prepare a timeout, like if you had given a block.
|
|
175
|
+
#
|
|
176
|
+
# You can rescue `Timeout::Error`, instead `TimeoutInterrupt::Error`, it will work too.
|
|
177
|
+
#
|
|
178
|
+
# It will call your given block, which has `seconds` seconds to end.
|
|
179
|
+
# If you want to prepare a timeout, which should be used many times,
|
|
180
|
+
# without giving `seconds` and `exception`, you can omit the block,
|
|
181
|
+
# so, `TimeoutInterruptSingleton#timeout` will return a `Proc`, which want to have the block.
|
|
182
|
+
#
|
|
183
|
+
# There is a problem with scoped timeouts. If you rescue a timeout in an other timeout,
|
|
184
|
+
# it's possible, that the other timeout will never timeout, because both are timed out at once.
|
|
185
|
+
# Than you need to call `TimeoutInterruptSingleton#timeout` without arguments.
|
|
186
|
+
# It will prepare the next timeout or it will raise it directy, if timed out.
|
|
187
|
+
#
|
|
188
|
+
# @note This method is useful, if you `include TimeoutInterrupt`. You can call it directly.
|
|
189
|
+
# @see TimeoutInterrupt.timeout
|
|
190
|
+
# @see TimeoutInterruptSingleton.timeout
|
|
191
|
+
# @raise exception
|
|
192
|
+
def timeout seconds = nil, exception = nil, &block
|
|
193
|
+
TimeoutInterruptSingleton.timeout seconds, exception, &block
|
|
72
194
|
end
|
|
73
195
|
end
|
data/timeout-interrupt.gemspec
CHANGED
|
@@ -1,68 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
Gem::Specification.new do |spec|
|
|
2
|
+
spec.name = "timeout-interrupt"
|
|
3
|
+
spec.version = "0.4.0"
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
spec.authors = ["Denis Knauf"]
|
|
6
|
+
spec.description = "Timeout-lib, which interrupts everything, also systemcalls. It uses libc-alarm."
|
|
7
|
+
spec.email = ["git+timeout-interrupt@denkn.at"]
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
s.date = "2013-03-07"
|
|
13
|
-
s.description = "Timeout-lib, which interrupts everything, also systemcalls. It uses libc-alarm."
|
|
14
|
-
s.email = "Denis.Knauf@gmail.com"
|
|
15
|
-
s.extra_rdoc_files = [
|
|
16
|
-
"LICENSE.txt",
|
|
17
|
-
"README.md"
|
|
18
|
-
]
|
|
19
|
-
s.files = [
|
|
20
|
-
".document",
|
|
21
|
-
"Gemfile",
|
|
22
|
-
"Gemfile.lock",
|
|
23
|
-
"LICENSE.txt",
|
|
24
|
-
"README.md",
|
|
25
|
-
"Rakefile",
|
|
26
|
-
"VERSION",
|
|
27
|
-
"lib/timeout_interrupt.rb",
|
|
28
|
-
"test/helper.rb",
|
|
29
|
-
"test/test_ruby-timeout-interrupt.rb",
|
|
30
|
-
"timeout-interrupt.gemspec"
|
|
31
|
-
]
|
|
32
|
-
s.homepage = "http://github.com/DenisKnauf/ruby-timeout-interrupt"
|
|
33
|
-
s.licenses = ["AGPLv3"]
|
|
34
|
-
s.require_paths = ["lib"]
|
|
35
|
-
s.rubygems_version = "1.8.11"
|
|
36
|
-
s.summary = "\"Interrupts systemcalls too.\""
|
|
9
|
+
spec.summary = "\"Interrupts systemcalls too.\""
|
|
10
|
+
spec.licenses = ["LGPLv3"]
|
|
37
11
|
|
|
38
|
-
|
|
39
|
-
|
|
12
|
+
spec.homepage = "https://git.denkn.at/deac/ruby-timeout-interrupt"
|
|
13
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.1.0")
|
|
40
14
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
s.add_dependency(%q<rdoc>, [">= 0"])
|
|
54
|
-
s.add_dependency(%q<bundler>, [">= 0"])
|
|
55
|
-
s.add_dependency(%q<jeweler>, [">= 0"])
|
|
56
|
-
s.add_dependency(%q<simplecov>, [">= 0"])
|
|
57
|
-
end
|
|
58
|
-
else
|
|
59
|
-
s.add_dependency(%q<ffi-libc>, [">= 0"])
|
|
60
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
|
61
|
-
s.add_dependency(%q<yard>, [">= 0"])
|
|
62
|
-
s.add_dependency(%q<rdoc>, [">= 0"])
|
|
63
|
-
s.add_dependency(%q<bundler>, [">= 0"])
|
|
64
|
-
s.add_dependency(%q<jeweler>, [">= 0"])
|
|
65
|
-
s.add_dependency(%q<simplecov>, [">= 0"])
|
|
66
|
-
end
|
|
67
|
-
end
|
|
15
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
16
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
|
17
|
+
spec.metadata["changelog_uri"] = spec.homepage
|
|
18
|
+
|
|
19
|
+
# Specify which files should be added to the gem when it is released.
|
|
20
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
21
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
|
22
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
23
|
+
end
|
|
24
|
+
spec.bindir = "bin"
|
|
25
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
26
|
+
spec.require_paths = ["lib"]
|
|
68
27
|
|
|
28
|
+
spec.add_runtime_dependency 'ffi-libc', '>= 0.1.1'
|
|
29
|
+
spec.add_development_dependency 'test-unit'
|
|
30
|
+
spec.add_development_dependency 'shoulda'
|
|
31
|
+
spec.add_development_dependency 'rake'
|
|
32
|
+
spec.add_development_dependency 'bundler'
|
|
33
|
+
end
|
metadata
CHANGED
|
@@ -1,138 +1,124 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: timeout-interrupt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 0.4.0
|
|
6
5
|
platform: ruby
|
|
7
6
|
authors:
|
|
8
7
|
- Denis Knauf
|
|
9
8
|
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 2021-12-12 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: ffi-libc
|
|
16
|
-
requirement:
|
|
17
|
-
none: false
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
18
16
|
requirements:
|
|
19
|
-
- -
|
|
17
|
+
- - ">="
|
|
20
18
|
- !ruby/object:Gem::Version
|
|
21
|
-
version:
|
|
19
|
+
version: 0.1.1
|
|
22
20
|
type: :runtime
|
|
23
21
|
prerelease: false
|
|
24
|
-
version_requirements:
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 0.1.1
|
|
25
27
|
- !ruby/object:Gem::Dependency
|
|
26
|
-
name:
|
|
27
|
-
requirement:
|
|
28
|
-
none: false
|
|
28
|
+
name: test-unit
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
30
|
requirements:
|
|
30
|
-
- -
|
|
31
|
+
- - ">="
|
|
31
32
|
- !ruby/object:Gem::Version
|
|
32
33
|
version: '0'
|
|
33
34
|
type: :development
|
|
34
35
|
prerelease: false
|
|
35
|
-
version_requirements:
|
|
36
|
-
- !ruby/object:Gem::Dependency
|
|
37
|
-
name: yard
|
|
38
|
-
requirement: &79914220 !ruby/object:Gem::Requirement
|
|
39
|
-
none: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
40
37
|
requirements:
|
|
41
|
-
- -
|
|
38
|
+
- - ">="
|
|
42
39
|
- !ruby/object:Gem::Version
|
|
43
40
|
version: '0'
|
|
44
|
-
type: :development
|
|
45
|
-
prerelease: false
|
|
46
|
-
version_requirements: *79914220
|
|
47
41
|
- !ruby/object:Gem::Dependency
|
|
48
|
-
name:
|
|
49
|
-
requirement:
|
|
50
|
-
none: false
|
|
42
|
+
name: shoulda
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
51
44
|
requirements:
|
|
52
|
-
- -
|
|
45
|
+
- - ">="
|
|
53
46
|
- !ruby/object:Gem::Version
|
|
54
47
|
version: '0'
|
|
55
48
|
type: :development
|
|
56
49
|
prerelease: false
|
|
57
|
-
version_requirements:
|
|
58
|
-
- !ruby/object:Gem::Dependency
|
|
59
|
-
name: bundler
|
|
60
|
-
requirement: &79907200 !ruby/object:Gem::Requirement
|
|
61
|
-
none: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
62
51
|
requirements:
|
|
63
|
-
- -
|
|
52
|
+
- - ">="
|
|
64
53
|
- !ruby/object:Gem::Version
|
|
65
54
|
version: '0'
|
|
66
|
-
type: :development
|
|
67
|
-
prerelease: false
|
|
68
|
-
version_requirements: *79907200
|
|
69
55
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
71
|
-
requirement:
|
|
72
|
-
none: false
|
|
56
|
+
name: rake
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
73
58
|
requirements:
|
|
74
|
-
- -
|
|
59
|
+
- - ">="
|
|
75
60
|
- !ruby/object:Gem::Version
|
|
76
61
|
version: '0'
|
|
77
62
|
type: :development
|
|
78
63
|
prerelease: false
|
|
79
|
-
version_requirements:
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
80
69
|
- !ruby/object:Gem::Dependency
|
|
81
|
-
name:
|
|
82
|
-
requirement:
|
|
83
|
-
none: false
|
|
70
|
+
name: bundler
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
84
72
|
requirements:
|
|
85
|
-
- -
|
|
73
|
+
- - ">="
|
|
86
74
|
- !ruby/object:Gem::Version
|
|
87
75
|
version: '0'
|
|
88
76
|
type: :development
|
|
89
77
|
prerelease: false
|
|
90
|
-
version_requirements:
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
91
83
|
description: Timeout-lib, which interrupts everything, also systemcalls. It uses libc-alarm.
|
|
92
|
-
email:
|
|
84
|
+
email:
|
|
85
|
+
- git+timeout-interrupt@denkn.at
|
|
93
86
|
executables: []
|
|
94
87
|
extensions: []
|
|
95
|
-
extra_rdoc_files:
|
|
96
|
-
- LICENSE.txt
|
|
97
|
-
- README.md
|
|
88
|
+
extra_rdoc_files: []
|
|
98
89
|
files:
|
|
99
|
-
- .
|
|
90
|
+
- ".gitignore"
|
|
100
91
|
- Gemfile
|
|
101
|
-
- Gemfile.lock
|
|
102
92
|
- LICENSE.txt
|
|
103
93
|
- README.md
|
|
104
94
|
- Rakefile
|
|
105
95
|
- VERSION
|
|
106
96
|
- lib/timeout_interrupt.rb
|
|
107
|
-
- test/helper.rb
|
|
108
|
-
- test/test_ruby-timeout-interrupt.rb
|
|
109
97
|
- timeout-interrupt.gemspec
|
|
110
|
-
homepage:
|
|
98
|
+
homepage: https://git.denkn.at/deac/ruby-timeout-interrupt
|
|
111
99
|
licenses:
|
|
112
|
-
-
|
|
100
|
+
- LGPLv3
|
|
101
|
+
metadata:
|
|
102
|
+
homepage_uri: https://git.denkn.at/deac/ruby-timeout-interrupt
|
|
103
|
+
source_code_uri: https://git.denkn.at/deac/ruby-timeout-interrupt
|
|
104
|
+
changelog_uri: https://git.denkn.at/deac/ruby-timeout-interrupt
|
|
113
105
|
post_install_message:
|
|
114
106
|
rdoc_options: []
|
|
115
107
|
require_paths:
|
|
116
108
|
- lib
|
|
117
109
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
|
-
none: false
|
|
119
110
|
requirements:
|
|
120
|
-
- -
|
|
111
|
+
- - ">="
|
|
121
112
|
- !ruby/object:Gem::Version
|
|
122
|
-
version:
|
|
123
|
-
segments:
|
|
124
|
-
- 0
|
|
125
|
-
hash: -567688307
|
|
113
|
+
version: 2.1.0
|
|
126
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
|
-
none: false
|
|
128
115
|
requirements:
|
|
129
|
-
- -
|
|
116
|
+
- - ">="
|
|
130
117
|
- !ruby/object:Gem::Version
|
|
131
118
|
version: '0'
|
|
132
119
|
requirements: []
|
|
133
|
-
|
|
134
|
-
rubygems_version: 1.8.11
|
|
120
|
+
rubygems_version: 3.1.2
|
|
135
121
|
signing_key:
|
|
136
|
-
specification_version:
|
|
137
|
-
summary:
|
|
122
|
+
specification_version: 4
|
|
123
|
+
summary: '"Interrupts systemcalls too."'
|
|
138
124
|
test_files: []
|
data/.document
DELETED
data/Gemfile.lock
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
GEM
|
|
2
|
-
remote: http://rubygems.org/
|
|
3
|
-
specs:
|
|
4
|
-
activesupport (3.2.12)
|
|
5
|
-
i18n (~> 0.6)
|
|
6
|
-
multi_json (~> 1.0)
|
|
7
|
-
bourne (1.1.2)
|
|
8
|
-
mocha (= 0.10.5)
|
|
9
|
-
ffi (1.1.0)
|
|
10
|
-
ffi-libc (0.0.5)
|
|
11
|
-
ffi (>= 0.6.0, <= 1.1.0)
|
|
12
|
-
git (1.2.5)
|
|
13
|
-
i18n (0.6.4)
|
|
14
|
-
jeweler (1.8.4)
|
|
15
|
-
bundler (~> 1.0)
|
|
16
|
-
git (>= 1.2.5)
|
|
17
|
-
rake
|
|
18
|
-
rdoc
|
|
19
|
-
json (1.7.7)
|
|
20
|
-
metaclass (0.0.1)
|
|
21
|
-
mocha (0.10.5)
|
|
22
|
-
metaclass (~> 0.0.1)
|
|
23
|
-
multi_json (1.6.1)
|
|
24
|
-
rake (10.0.3)
|
|
25
|
-
rdoc (4.0.0)
|
|
26
|
-
json (~> 1.4)
|
|
27
|
-
shoulda (3.3.2)
|
|
28
|
-
shoulda-context (~> 1.0.1)
|
|
29
|
-
shoulda-matchers (~> 1.4.1)
|
|
30
|
-
shoulda-context (1.0.2)
|
|
31
|
-
shoulda-matchers (1.4.2)
|
|
32
|
-
activesupport (>= 3.0.0)
|
|
33
|
-
bourne (~> 1.1.2)
|
|
34
|
-
simplecov (0.7.1)
|
|
35
|
-
multi_json (~> 1.0)
|
|
36
|
-
simplecov-html (~> 0.7.1)
|
|
37
|
-
simplecov-html (0.7.1)
|
|
38
|
-
yard (0.8.5.2)
|
|
39
|
-
|
|
40
|
-
PLATFORMS
|
|
41
|
-
ruby
|
|
42
|
-
|
|
43
|
-
DEPENDENCIES
|
|
44
|
-
bundler
|
|
45
|
-
ffi-libc
|
|
46
|
-
jeweler
|
|
47
|
-
rdoc
|
|
48
|
-
shoulda
|
|
49
|
-
simplecov
|
|
50
|
-
yard
|
data/test/helper.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
require 'rubygems'
|
|
2
|
-
require 'bundler'
|
|
3
|
-
begin
|
|
4
|
-
Bundler.setup(:default, :development)
|
|
5
|
-
rescue Bundler::BundlerError => e
|
|
6
|
-
$stderr.puts e.message
|
|
7
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
|
8
|
-
exit e.status_code
|
|
9
|
-
end
|
|
10
|
-
require 'test/unit'
|
|
11
|
-
require 'shoulda'
|
|
12
|
-
|
|
13
|
-
require 'timeout'
|
|
14
|
-
require 'benchmark'
|
|
15
|
-
require 'ffi/libc'
|
|
16
|
-
|
|
17
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
18
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
19
|
-
|
|
20
|
-
require 'timeout_interrupt'
|
|
21
|
-
|
|
22
|
-
class Test::Unit::TestCase
|
|
23
|
-
end
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
require 'helper'
|
|
2
|
-
|
|
3
|
-
class TestRubyTimeoutInterrupt < Test::Unit::TestCase
|
|
4
|
-
def blocking
|
|
5
|
-
t = FFI::LibC.fopen '/dev/ptmx', 'r'
|
|
6
|
-
b = FFI::LibC.malloc 1025
|
|
7
|
-
s = FFI::LibC.fread b, 1, 1024, t
|
|
8
|
-
ensure
|
|
9
|
-
FFI::LibC.fclose t if t
|
|
10
|
-
FFI::LibC.free b if b
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def assert_no_defined_timeout_yet
|
|
14
|
-
assert TimeoutInterruptSingleton.timeouts.empty?, "For testing, no timeout should be defined, yet!"
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def print_timeouts pre
|
|
18
|
-
puts "#{pre}: < #{TimeoutInterruptSingleton.timeouts.map {|k,(a,_b,_e)| "#{k.inspect}: #{a.strftime '%H:%M:%S'} (#{a-Time.now})" }.join ', '} >"
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# For testing raising scoped Timeout.
|
|
22
|
-
class TimeoutError < Exception
|
|
23
|
-
end
|
|
24
|
-
# For testing raising scoped TimeoutInterrupt.
|
|
25
|
-
class TimeoutInterruptError < Exception
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
context "Long really blocking calls" do
|
|
29
|
-
should "not be interrupted by the old Timeout" do
|
|
30
|
-
time = Benchmark.realtime do
|
|
31
|
-
assert_nothing_raised TimeoutError, "Unexpected time out. Your Ruby implementation can time out with old Timeout? You need not TimeoutInterrupt. But it is ok. You can ignore this Error. :)" do
|
|
32
|
-
assert_raise TimeoutInterruptError, "Ohoh. TimeoutInterrupt should be raised." do
|
|
33
|
-
TimeoutInterrupt.timeout 5, TimeoutInterruptError do
|
|
34
|
-
Timeout.timeout 1, TimeoutError do
|
|
35
|
-
blocking
|
|
36
|
-
assert false, "Should be unreachable!"
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
assert 3 < time, "Did timeout!"
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
should "be interrupted by the new TimeoutInterrupt" do
|
|
46
|
-
time = Benchmark.realtime do
|
|
47
|
-
assert_raise TimeoutInterrupt::Error, "It should be timed out, why it did not raise TimeoutInterrupt::Error?" do
|
|
48
|
-
TimeoutInterrupt.timeout 1 do
|
|
49
|
-
blocking
|
|
50
|
-
assert false, "Should be unreachable!"
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
assert 3 > time, "Did not interrupt."
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
should "interrupt scoped timeout, but not time out the outer timeout" do
|
|
59
|
-
assert_no_defined_timeout_yet
|
|
60
|
-
assert_raise TimeoutInterruptError, "It should be timed out, why it did not raise TimeoutInterruptError?" do
|
|
61
|
-
assert_nothing_raised Timeout::Error, "Oh, outer timeout was timed out. Your machine must be slow, or there is a bug" do
|
|
62
|
-
TimeoutInterrupt.timeout 10 do
|
|
63
|
-
TimeoutInterrupt.timeout 1, TimeoutInterruptError do
|
|
64
|
-
Kernel.sleep 2
|
|
65
|
-
end
|
|
66
|
-
assert false, "Should be unreachable!"
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
assert TimeoutInterruptSingleton.timeouts.empty?, "There are timeouts defined, yet!"
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
should "clear timeouts, if not timed out, too." do
|
|
74
|
-
assert_no_defined_timeout_yet
|
|
75
|
-
TimeoutInterrupt.timeout(10) {}
|
|
76
|
-
assert TimeoutInterruptSingleton.timeouts.empty?, "There are timeouts defined, yet!"
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
class CustomException <Exception
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
should "raise custom exception." do
|
|
83
|
-
assert_raise CustomException, "Custom exceptions do not work." do
|
|
84
|
-
TimeoutInterrupt.timeout 1, CustomException do
|
|
85
|
-
sleep 2
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
context "A prepared timeout (Proc)" do
|
|
91
|
-
should "be returned by calling timeout without a block" do
|
|
92
|
-
assert_no_defined_timeout_yet
|
|
93
|
-
assert TimeoutInterrupt.timeout(10).kind_of?( Proc), "Did not return a Proc."
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
should "run with once given timeout" do
|
|
97
|
-
assert_no_defined_timeout_yet
|
|
98
|
-
to = TimeoutInterrupt.timeout 10
|
|
99
|
-
called = false
|
|
100
|
-
to.call { called = true }
|
|
101
|
-
assert called, "Did not called."
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
should "raise custom exception" do
|
|
105
|
-
assert_raise CustomException, "Custom exceptions do not work." do
|
|
106
|
-
prepared = TimeoutInterrupt.timeout 1, CustomException
|
|
107
|
-
prepared.call { sleep 2 }
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
should "not be scopeable, without manualy setup after rescue and 2 time outs at once" do
|
|
112
|
-
prepared = TimeoutInterrupt.timeout 1
|
|
113
|
-
assert_no_defined_timeout_yet
|
|
114
|
-
called = false
|
|
115
|
-
prepared.call do
|
|
116
|
-
assert_raise TimeoutInterrupt::Error, 'It should time out after one second, but it did not.' do
|
|
117
|
-
prepared.call { 2; sleep 2 }
|
|
118
|
-
end
|
|
119
|
-
called = true
|
|
120
|
-
end
|
|
121
|
-
assert called, "It's true, it should be called, also if not expected."
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
should "be scopeable, with manualy setup after rescue, also if 2 time outs at once." do
|
|
125
|
-
prepared = TimeoutInterrupt.timeout 1
|
|
126
|
-
assert_no_defined_timeout_yet
|
|
127
|
-
prepared.call do
|
|
128
|
-
assert_raise TimeoutInterrupt::Error, 'It should time out after one second, but it did not.' do
|
|
129
|
-
prepared.call { sleep 2 }
|
|
130
|
-
end
|
|
131
|
-
assert_raise TimeoutInterrupt::Error, 'Manualy called timeout setup did not raise.' do
|
|
132
|
-
TimeoutInterrupt.timeout
|
|
133
|
-
end
|
|
134
|
-
assert true, "Should never be reached."
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
class IncludeModuleTest
|
|
140
|
-
include TimeoutInterrupt
|
|
141
|
-
def please_timeout after
|
|
142
|
-
timeout after do
|
|
143
|
-
sleep after+10
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
context "Included module" do
|
|
149
|
-
should "provide timeout too" do
|
|
150
|
-
assert_raise TimeoutInterrupt::Error, "Included timeout can not be used?" do
|
|
151
|
-
IncludeModuleTest.new.please_timeout 2
|
|
152
|
-
end
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
end
|