timeout-interrupt 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
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
data/Gemfile.lock ADDED
@@ -0,0 +1,50 @@
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/LICENSE.txt ADDED
@@ -0,0 +1,165 @@
1
+ GNU LESSER GENERAL PUBLIC LICENSE
2
+ Version 3, 29 June 2007
3
+
4
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5
+ Everyone is permitted to copy and distribute verbatim copies
6
+ of this license document, but changing it is not allowed.
7
+
8
+
9
+ This version of the GNU Lesser General Public License incorporates
10
+ the terms and conditions of version 3 of the GNU General Public
11
+ License, supplemented by the additional permissions listed below.
12
+
13
+ 0. Additional Definitions.
14
+
15
+ As used herein, "this License" refers to version 3 of the GNU Lesser
16
+ General Public License, and the "GNU GPL" refers to version 3 of the GNU
17
+ General Public License.
18
+
19
+ "The Library" refers to a covered work governed by this License,
20
+ other than an Application or a Combined Work as defined below.
21
+
22
+ An "Application" is any work that makes use of an interface provided
23
+ by the Library, but which is not otherwise based on the Library.
24
+ Defining a subclass of a class defined by the Library is deemed a mode
25
+ of using an interface provided by the Library.
26
+
27
+ A "Combined Work" is a work produced by combining or linking an
28
+ Application with the Library. The particular version of the Library
29
+ with which the Combined Work was made is also called the "Linked
30
+ Version".
31
+
32
+ The "Minimal Corresponding Source" for a Combined Work means the
33
+ Corresponding Source for the Combined Work, excluding any source code
34
+ for portions of the Combined Work that, considered in isolation, are
35
+ based on the Application, and not on the Linked Version.
36
+
37
+ The "Corresponding Application Code" for a Combined Work means the
38
+ object code and/or source code for the Application, including any data
39
+ and utility programs needed for reproducing the Combined Work from the
40
+ Application, but excluding the System Libraries of the Combined Work.
41
+
42
+ 1. Exception to Section 3 of the GNU GPL.
43
+
44
+ You may convey a covered work under sections 3 and 4 of this License
45
+ without being bound by section 3 of the GNU GPL.
46
+
47
+ 2. Conveying Modified Versions.
48
+
49
+ If you modify a copy of the Library, and, in your modifications, a
50
+ facility refers to a function or data to be supplied by an Application
51
+ that uses the facility (other than as an argument passed when the
52
+ facility is invoked), then you may convey a copy of the modified
53
+ version:
54
+
55
+ a) under this License, provided that you make a good faith effort to
56
+ ensure that, in the event an Application does not supply the
57
+ function or data, the facility still operates, and performs
58
+ whatever part of its purpose remains meaningful, or
59
+
60
+ b) under the GNU GPL, with none of the additional permissions of
61
+ this License applicable to that copy.
62
+
63
+ 3. Object Code Incorporating Material from Library Header Files.
64
+
65
+ The object code form of an Application may incorporate material from
66
+ a header file that is part of the Library. You may convey such object
67
+ code under terms of your choice, provided that, if the incorporated
68
+ material is not limited to numerical parameters, data structure
69
+ layouts and accessors, or small macros, inline functions and templates
70
+ (ten or fewer lines in length), you do both of the following:
71
+
72
+ a) Give prominent notice with each copy of the object code that the
73
+ Library is used in it and that the Library and its use are
74
+ covered by this License.
75
+
76
+ b) Accompany the object code with a copy of the GNU GPL and this license
77
+ document.
78
+
79
+ 4. Combined Works.
80
+
81
+ You may convey a Combined Work under terms of your choice that,
82
+ taken together, effectively do not restrict modification of the
83
+ portions of the Library contained in the Combined Work and reverse
84
+ engineering for debugging such modifications, if you also do each of
85
+ the following:
86
+
87
+ a) Give prominent notice with each copy of the Combined Work that
88
+ the Library is used in it and that the Library and its use are
89
+ covered by this License.
90
+
91
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
92
+ document.
93
+
94
+ c) For a Combined Work that displays copyright notices during
95
+ execution, include the copyright notice for the Library among
96
+ these notices, as well as a reference directing the user to the
97
+ copies of the GNU GPL and this license document.
98
+
99
+ d) Do one of the following:
100
+
101
+ 0) Convey the Minimal Corresponding Source under the terms of this
102
+ License, and the Corresponding Application Code in a form
103
+ suitable for, and under terms that permit, the user to
104
+ recombine or relink the Application with a modified version of
105
+ the Linked Version to produce a modified Combined Work, in the
106
+ manner specified by section 6 of the GNU GPL for conveying
107
+ Corresponding Source.
108
+
109
+ 1) Use a suitable shared library mechanism for linking with the
110
+ Library. A suitable mechanism is one that (a) uses at run time
111
+ a copy of the Library already present on the user's computer
112
+ system, and (b) will operate properly with a modified version
113
+ of the Library that is interface-compatible with the Linked
114
+ Version.
115
+
116
+ e) Provide Installation Information, but only if you would otherwise
117
+ be required to provide such information under section 6 of the
118
+ GNU GPL, and only to the extent that such information is
119
+ necessary to install and execute a modified version of the
120
+ Combined Work produced by recombining or relinking the
121
+ Application with a modified version of the Linked Version. (If
122
+ you use option 4d0, the Installation Information must accompany
123
+ the Minimal Corresponding Source and Corresponding Application
124
+ Code. If you use option 4d1, you must provide the Installation
125
+ Information in the manner specified by section 6 of the GNU GPL
126
+ for conveying Corresponding Source.)
127
+
128
+ 5. Combined Libraries.
129
+
130
+ You may place library facilities that are a work based on the
131
+ Library side by side in a single library together with other library
132
+ facilities that are not Applications and are not covered by this
133
+ License, and convey such a combined library under terms of your
134
+ choice, if you do both of the following:
135
+
136
+ a) Accompany the combined library with a copy of the same work based
137
+ on the Library, uncombined with any other library facilities,
138
+ conveyed under the terms of this License.
139
+
140
+ b) Give prominent notice with the combined library that part of it
141
+ is a work based on the Library, and explaining where to find the
142
+ accompanying uncombined form of the same work.
143
+
144
+ 6. Revised Versions of the GNU Lesser General Public License.
145
+
146
+ The Free Software Foundation may publish revised and/or new versions
147
+ of the GNU Lesser General Public License from time to time. Such new
148
+ versions will be similar in spirit to the present version, but may
149
+ differ in detail to address new problems or concerns.
150
+
151
+ Each version is given a distinguishing version number. If the
152
+ Library as you received it specifies that a certain numbered version
153
+ of the GNU Lesser General Public License "or any later version"
154
+ applies to it, you have the option of following the terms and
155
+ conditions either of that published version or of any later version
156
+ published by the Free Software Foundation. If the Library as you
157
+ received it does not specify a version number of the GNU Lesser
158
+ General Public License, you may choose any version of the GNU Lesser
159
+ General Public License ever published by the Free Software Foundation.
160
+
161
+ If the Library as you received it specifies that a proxy can decide
162
+ whether future versions of the GNU Lesser General Public License shall
163
+ apply, that proxy's public statement of acceptance of any version is
164
+ permanent authorization for you to choose that version for the
165
+ Library.
data/README.md ADDED
@@ -0,0 +1,17 @@
1
+ timeout-interrupt
2
+ =================
3
+
4
+ Works like ruby's timeout, but interrupts every call, also syscalls, which blocks the hole ruby-process.
5
+
6
+ It uses POSIX's alarm and traps ALRM-signals.
7
+
8
+ Known limitations bacause of alarm and ALRM are, that you can not use alarm or trap ALRM.
9
+
10
+ Do not forget, syscall can have allocated memory.
11
+ If you interrupt a call, which can not free his allocations, you will have a memory leak.
12
+ So, use it only, if your process did not live any longer or if you call something, which never allocate mem
13
+
14
+ Copyleft
15
+ =========
16
+
17
+ Copyright (c) 2013 Denis Knauf. See LICENSE.txt for further details.
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
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
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ 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 ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,49 @@
1
+ require 'ffi/libc'
2
+ require 'timeout'
3
+
4
+ module FFI
5
+ module LibC
6
+ attach_function :alarm, [:uint], :uint unless FFI::LibC.respond_to? :alarm
7
+ end
8
+ end
9
+
10
+ module TimeoutInterrupt
11
+ def self.timeouts
12
+ @timeouts ||= {}
13
+ end
14
+
15
+ def self.alarm_trap sig
16
+ key, (at, bt) = TimeoutInterrupt.timeouts.min_by {|key,(at,bt)| at }
17
+ return if Time.now < at
18
+ raise Timeout::Error, 'execution expired', bt
19
+ end
20
+
21
+ def self.setup_timeout
22
+ if TimeoutInterrupt.timeouts.empty?
23
+ Signal.trap( 'ALRM') {}
24
+ FFI::LibC.alarm 0
25
+ else
26
+ key, (at, bt) = TimeoutInterrupt.timeouts.min_by {|key,(at,bt)| at }
27
+ secs = (at - Time.now).to_i+1
28
+ TimeoutInterrupt.alarm_trap if 1 > secs
29
+ Signal.trap 'ALRM', &TimeoutInterrupt.method( :alarm_trap)
30
+ FFI::LibC.alarm secs
31
+ end
32
+ end
33
+
34
+ def self.timeout seconds
35
+ seconds = seconds.to_i
36
+ raise Timeout::Error, "Timeout must be longer than '0' seconds." unless 0 < seconds
37
+ return lambda {|&e| self.timeout seconds, &e } unless block_given?
38
+ at = Time.now + seconds
39
+ key, bt = Random.rand( 2**64-1), Kernel.caller
40
+ begin
41
+ TimeoutInterrupt.timeouts[key] = [at, bt]
42
+ TimeoutInterrupt.setup_timeout
43
+ yield
44
+ ensure
45
+ TimeoutInterrupt.timeouts.delete key
46
+ TimeoutInterrupt.setup_timeout
47
+ end
48
+ end
49
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,23 @@
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
@@ -0,0 +1,80 @@
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 TimeoutInterrupt.timeouts.empty?, "For testing, no timeout should be defined, yet!"
15
+ end
16
+
17
+ should "not interrupt a long blocking call with the old Timeout" do
18
+ time = Benchmark.realtime do
19
+ begin
20
+ TimeoutInterrupt.timeout(5) do
21
+ Timeout.timeout(1) do
22
+ blocking
23
+ assert false, "Should be unreachable!"
24
+ end
25
+ end
26
+ rescue Timeout::Error
27
+ :ok
28
+ end
29
+ end
30
+ assert 3 < time, "Did timeout!"
31
+ end
32
+
33
+ should "interrupt a long blocking call with the new TimeoutInterrupt" do
34
+ time = Benchmark.realtime do
35
+ begin
36
+ TimeoutInterrupt.timeout(1) do
37
+ blocking
38
+ assert false, "Should be unreachable!"
39
+ end
40
+ rescue Timeout::Error
41
+ :ok
42
+ end
43
+ end
44
+ assert 3 > time, "Did not interrupt."
45
+ end
46
+
47
+ should "interrupt scoped timeout, but not outer timeout" do
48
+ assert_no_defined_timeout_yet
49
+ begin
50
+ TimeoutInterrupt.timeout(10) do
51
+ TimeoutInterrupt.timeout(1) do
52
+ Kernel.sleep 2
53
+ end
54
+ assert false, "Should be unreachable!"
55
+ end
56
+ rescue Timeout::Error
57
+ :ok
58
+ end
59
+ assert TimeoutInterrupt.timeouts.empty?, "There are timeouts defined, yet!"
60
+ end
61
+
62
+ should "clear timeouts, if not timed out, too." do
63
+ assert_no_defined_timeout_yet
64
+ TimeoutInterrupt.timeout(10) {}
65
+ assert TimeoutInterrupt.timeouts.empty?, "There are timeouts defined, yet!"
66
+ end
67
+
68
+ should "return a Proc if now block given, but do not create a timeout." do
69
+ assert_no_defined_timeout_yet
70
+ assert TimeoutInterrupt.timeout(10).kind_of?( Proc), "Did not return a Proc."
71
+ end
72
+
73
+ should "run a returned Proc with given timeout." do
74
+ assert_no_defined_timeout_yet
75
+ to = TimeoutInterrupt.timeout(10)
76
+ called = false
77
+ to.call { called = true }
78
+ assert called, "Did not called."
79
+ end
80
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: timeout-interrupt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Denis Knauf
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ffi-libc
16
+ requirement: &72349180 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *72349180
25
+ - !ruby/object:Gem::Dependency
26
+ name: shoulda
27
+ requirement: &72348250 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *72348250
36
+ - !ruby/object:Gem::Dependency
37
+ name: yard
38
+ requirement: &72367400 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *72367400
47
+ - !ruby/object:Gem::Dependency
48
+ name: rdoc
49
+ requirement: &72364150 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *72364150
58
+ - !ruby/object:Gem::Dependency
59
+ name: bundler
60
+ requirement: &72360610 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *72360610
69
+ - !ruby/object:Gem::Dependency
70
+ name: jeweler
71
+ requirement: &72357200 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *72357200
80
+ - !ruby/object:Gem::Dependency
81
+ name: simplecov
82
+ requirement: &72355990 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *72355990
91
+ description: Timeout-lib, which interrupts everything, also systemcalls. It uses libc-alarm.
92
+ email: Denis.Knauf@gmail.com
93
+ executables: []
94
+ extensions: []
95
+ extra_rdoc_files:
96
+ - LICENSE.txt
97
+ - README.md
98
+ files:
99
+ - .document
100
+ - Gemfile
101
+ - Gemfile.lock
102
+ - LICENSE.txt
103
+ - README.md
104
+ - Rakefile
105
+ - VERSION
106
+ - lib/timeout_interrupt.rb
107
+ - test/helper.rb
108
+ - test/test_ruby-timeout-interrupt.rb
109
+ homepage: http://github.com/DenisKnauf/ruby-timeout-interrupt
110
+ licenses:
111
+ - AGPLv3
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ segments:
123
+ - 0
124
+ hash: -502487251
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ none: false
127
+ requirements:
128
+ - - ! '>='
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ requirements: []
132
+ rubyforge_project:
133
+ rubygems_version: 1.8.11
134
+ signing_key:
135
+ specification_version: 3
136
+ summary: ! '"Interrupts systemcalls too."'
137
+ test_files: []