timeout_ext 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/COPYING +510 -0
- data/MANIFEST +51 -0
- data/README +15 -0
- data/Rakefile +28 -0
- data/ext/timeout_ext/.gitignore +3 -0
- data/ext/timeout_ext/ccan-bits.c +7 -0
- data/ext/timeout_ext/ccan/array_size/LICENSE +28 -0
- data/ext/timeout_ext/ccan/array_size/_info +46 -0
- data/ext/timeout_ext/ccan/array_size/array_size.h +26 -0
- data/ext/timeout_ext/ccan/build_assert/LICENSE +28 -0
- data/ext/timeout_ext/ccan/build_assert/_info +49 -0
- data/ext/timeout_ext/ccan/build_assert/build_assert.h +40 -0
- data/ext/timeout_ext/ccan/check_type/LICENSE +28 -0
- data/ext/timeout_ext/ccan/check_type/_info +33 -0
- data/ext/timeout_ext/ccan/check_type/check_type.h +64 -0
- data/ext/timeout_ext/ccan/compiler/LICENSE +28 -0
- data/ext/timeout_ext/ccan/compiler/_info +64 -0
- data/ext/timeout_ext/ccan/compiler/compiler.h +231 -0
- data/ext/timeout_ext/ccan/container_of/LICENSE +28 -0
- data/ext/timeout_ext/ccan/container_of/_info +65 -0
- data/ext/timeout_ext/ccan/container_of/container_of.h +145 -0
- data/ext/timeout_ext/ccan/ilog/LICENSE +28 -0
- data/ext/timeout_ext/ccan/ilog/_info +50 -0
- data/ext/timeout_ext/ccan/ilog/ilog.c +141 -0
- data/ext/timeout_ext/ccan/ilog/ilog.h +151 -0
- data/ext/timeout_ext/ccan/list/LICENSE +17 -0
- data/ext/timeout_ext/ccan/list/_info +72 -0
- data/ext/timeout_ext/ccan/list/list.h +842 -0
- data/ext/timeout_ext/ccan/str/LICENSE +28 -0
- data/ext/timeout_ext/ccan/str/_info +52 -0
- data/ext/timeout_ext/ccan/str/str.h +228 -0
- data/ext/timeout_ext/ccan/str/str_debug.h +30 -0
- data/ext/timeout_ext/ccan/time/LICENSE +17 -0
- data/ext/timeout_ext/ccan/time/_info +57 -0
- data/ext/timeout_ext/ccan/time/time.c +138 -0
- data/ext/timeout_ext/ccan/time/time.h +753 -0
- data/ext/timeout_ext/ccan/timer/LICENSE +510 -0
- data/ext/timeout_ext/ccan/timer/_info +79 -0
- data/ext/timeout_ext/ccan/timer/design.txt +76 -0
- data/ext/timeout_ext/ccan/timer/timer.c +524 -0
- data/ext/timeout_ext/ccan/timer/timer.h +211 -0
- data/ext/timeout_ext/depend +17 -0
- data/ext/timeout_ext/extconf.rb +50 -0
- data/ext/timeout_ext/licenses/BSD-MIT +17 -0
- data/ext/timeout_ext/licenses/CC0 +28 -0
- data/ext/timeout_ext/licenses/LGPL-2.1 +510 -0
- data/ext/timeout_ext/missing/stdbool/stdbool.h +20 -0
- data/ext/timeout_ext/timeout_ext.c +114 -0
- data/test/test_timeout_ext.rb +44 -0
- data/timeout_ext.gemspec +30 -0
- metadata +126 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
/*
|
2
|
+
* missing/stdbool.h: Quick alternative of C99 stdbool.h
|
3
|
+
*/
|
4
|
+
|
5
|
+
#ifndef _MISSING_STDBOOL_H_
|
6
|
+
#define _MISSING_STDBOOL_H_
|
7
|
+
|
8
|
+
#ifndef __cplusplus
|
9
|
+
|
10
|
+
#define bool _Bool
|
11
|
+
#define true 1
|
12
|
+
#define false 0
|
13
|
+
|
14
|
+
#ifndef HAVE__BOOL /* AC_HEADER_STDBOOL in configure.ac */
|
15
|
+
typedef int _Bool;
|
16
|
+
#endif /* HAVE__BOOL */
|
17
|
+
|
18
|
+
#endif /* __cplusplus */
|
19
|
+
|
20
|
+
#endif /* _MISSING_STDBOOL_H_ */
|
@@ -0,0 +1,114 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) 2018 Ruby hackers <ruby-core@ruby-lang.org>
|
3
|
+
* License: LGPL-2.1+ <https://www.gnu.org/licenses/lgpl-2.1.txt>
|
4
|
+
*/
|
5
|
+
#include <ruby/ruby.h>
|
6
|
+
#include <ruby/intern.h>
|
7
|
+
#include <ccan/timer/timer.h>
|
8
|
+
|
9
|
+
static VALUE eUncaughtThrow;
|
10
|
+
|
11
|
+
static void *
|
12
|
+
rb_timers_create(void)
|
13
|
+
{
|
14
|
+
struct timers *t = ALLOC(struct timers);
|
15
|
+
|
16
|
+
timers_init(t, time_mono());
|
17
|
+
|
18
|
+
return t;
|
19
|
+
}
|
20
|
+
|
21
|
+
static void
|
22
|
+
rb_timer_add(struct timers *timers, struct timer *t, struct timespec *ts)
|
23
|
+
{
|
24
|
+
struct timerel rel;
|
25
|
+
rel.ts = *ts;
|
26
|
+
timer_init(t);
|
27
|
+
timer_addrel(timers, t, rel);
|
28
|
+
}
|
29
|
+
|
30
|
+
static void *
|
31
|
+
rb_timers_expire(struct timers *timers)
|
32
|
+
{
|
33
|
+
return timers_expire(timers, time_mono());
|
34
|
+
}
|
35
|
+
|
36
|
+
static void *
|
37
|
+
rb_timers_earliest(struct timers *timers, struct timespec *rel)
|
38
|
+
{
|
39
|
+
struct timemono now;
|
40
|
+
struct timemono first;
|
41
|
+
|
42
|
+
if (!timer_earliest(timers, &first)) return 0;
|
43
|
+
|
44
|
+
now = time_mono();
|
45
|
+
if (time_greater_(first.ts, now.ts)) {
|
46
|
+
struct timerel ret = timemono_between(first, now);
|
47
|
+
*rel = ret.ts;
|
48
|
+
}
|
49
|
+
else {
|
50
|
+
rel->tv_sec = 0;
|
51
|
+
rel->tv_nsec = 0;
|
52
|
+
}
|
53
|
+
return rel;
|
54
|
+
}
|
55
|
+
|
56
|
+
void
|
57
|
+
rb_timers_destroy(void *p)
|
58
|
+
{
|
59
|
+
struct timers *timers = p;
|
60
|
+
timers_cleanup(timers);
|
61
|
+
xfree(timers);
|
62
|
+
}
|
63
|
+
|
64
|
+
static struct rb_timers_type0 ccan_timers = {
|
65
|
+
/* .create = */ rb_timers_create,
|
66
|
+
/* .add = */ rb_timer_add,
|
67
|
+
/* .expire = */ rb_timers_expire,
|
68
|
+
/* .earliest = */ rb_timers_earliest,
|
69
|
+
/* .destroy = */ rb_timers_destroy
|
70
|
+
};
|
71
|
+
|
72
|
+
static VALUE
|
73
|
+
begin_throw(VALUE self)
|
74
|
+
{
|
75
|
+
rb_throw_obj(self, self);
|
76
|
+
return self;
|
77
|
+
}
|
78
|
+
|
79
|
+
static VALUE
|
80
|
+
rescue_throw(VALUE ignore, VALUE err)
|
81
|
+
{
|
82
|
+
return Qfalse;
|
83
|
+
}
|
84
|
+
|
85
|
+
/*
|
86
|
+
* We don't want to generate a backtrace like the version
|
87
|
+
* in timeout.rb does. We also want to raise the same
|
88
|
+
* exception object so rb_s_timeout (in core) can match
|
89
|
+
* against it without relying on an extra proc for:
|
90
|
+
*
|
91
|
+
* proc { |exception| return yield(sec) }
|
92
|
+
*/
|
93
|
+
static VALUE
|
94
|
+
rb_timeout_error_exception(int argc, VALUE *argv, VALUE self)
|
95
|
+
{
|
96
|
+
if (rb_attr_get(self, rb_intern("@thread")) == rb_thread_current()) {
|
97
|
+
rb_rescue2(begin_throw, self, rescue_throw, Qfalse, eUncaughtThrow, 0);
|
98
|
+
}
|
99
|
+
return self;
|
100
|
+
}
|
101
|
+
|
102
|
+
void
|
103
|
+
Init_timeout_ext(void)
|
104
|
+
{
|
105
|
+
#undef rb_intern
|
106
|
+
VALUE mTimeout = rb_const_get(rb_cObject, rb_intern("Timeout"));
|
107
|
+
VALUE cError = rb_const_get(mTimeout, rb_intern("Error"));
|
108
|
+
eUncaughtThrow = rb_const_get(rb_cObject, rb_intern("UncaughtThrowError"));
|
109
|
+
rb_timers = &ccan_timers;
|
110
|
+
rb_define_method(mTimeout, "timeout", rb_s_timeout, -1);
|
111
|
+
rb_define_singleton_method(mTimeout, "timeout", rb_s_timeout, -1);
|
112
|
+
rb_undef_method(cError, "exception");
|
113
|
+
rb_define_method(cError, "exception", rb_timeout_error_exception, -1);
|
114
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'timeout'
|
3
|
+
require 'timeout_ext'
|
4
|
+
|
5
|
+
class TestTimeoutExt < Test::Unit::TestCase
|
6
|
+
class T
|
7
|
+
include Timeout
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_override
|
11
|
+
res = Timeout.method(:timeout).source_location.inspect
|
12
|
+
assert_not_match %r{\.rb\b}, res, res
|
13
|
+
res = Timeout::Error.new.method(:exception).source_location.inspect
|
14
|
+
assert_not_match %r{\.rb\b}, res, res
|
15
|
+
T.new.method(:timeout).source_location.inspect
|
16
|
+
assert_not_match %r{\.rb\b}, res, res
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_basic_timeout
|
20
|
+
Timeout.timeout(nil) { sleep 0.01 }
|
21
|
+
Timeout.timeout(1) { assert_equal 1, Thread.list.size }
|
22
|
+
assert_raise(Timeout::Error) do
|
23
|
+
Timeout.timeout(0.1) do
|
24
|
+
assert_equal 1, Thread.list.size
|
25
|
+
sleep
|
26
|
+
end
|
27
|
+
end
|
28
|
+
t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
29
|
+
assert_raise(Timeout::Error) do
|
30
|
+
Timeout.timeout(0.1) do
|
31
|
+
assert_equal 1, Thread.list.size
|
32
|
+
sleep 2
|
33
|
+
end
|
34
|
+
end
|
35
|
+
t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
36
|
+
assert_operator(t1 - t0, :<=, 1)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_different_exception
|
40
|
+
assert_raise(RuntimeError.new('hello world')) do
|
41
|
+
Timeout.timeout(10) { raise 'hello world' }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/timeout_ext.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
git_manifest = `git ls-files 2>/dev/null`.split("\n")
|
2
|
+
manifest = File.exist?('MANIFEST') ?
|
3
|
+
File.readlines('MANIFEST').map!(&:chomp).delete_if(&:empty?) : git_manifest
|
4
|
+
if git_manifest[0] && manifest != git_manifest
|
5
|
+
tmp = "MANIFEST.#$$.tmp"
|
6
|
+
File.open(tmp, 'w') { |fp| fp.puts(git_manifest.join("\n")) }
|
7
|
+
File.rename(tmp, 'MANIFEST')
|
8
|
+
system('git add MANIFEST')
|
9
|
+
end
|
10
|
+
|
11
|
+
Gem::Specification.new do |s|
|
12
|
+
s.name = 'timeout_ext'
|
13
|
+
s.version = '0.0.0'
|
14
|
+
s.homepage = 'https://80x24.org/timeout_ext.git'
|
15
|
+
s.authors = ["Ruby hackers"]
|
16
|
+
s.summary = 'enhancement to timeout.rb in the Ruby stdlib'
|
17
|
+
s.files = manifest
|
18
|
+
s.description = <<~EOF
|
19
|
+
Uses the CCAN timer implementation and hooks in the main Ruby VM
|
20
|
+
to speed up timeout.rb
|
21
|
+
EOF
|
22
|
+
|
23
|
+
s.email = %q{normal@ruby-lang.org}
|
24
|
+
s.test_files = Dir['test/test_*.rb']
|
25
|
+
s.extensions = %w(ext/timeout_ext/extconf.rb)
|
26
|
+
|
27
|
+
s.add_development_dependency('test-unit', '~> 3.0')
|
28
|
+
s.add_development_dependency('rake-compiler', '~> 1.0')
|
29
|
+
s.licenses = %w(LGPL-2.1+)
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: timeout_ext
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ruby hackers
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-06-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: test-unit
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake-compiler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
41
|
+
description: |
|
42
|
+
Uses the CCAN timer implementation and hooks in the main Ruby VM
|
43
|
+
to speed up timeout.rb
|
44
|
+
email: normal@ruby-lang.org
|
45
|
+
executables: []
|
46
|
+
extensions:
|
47
|
+
- ext/timeout_ext/extconf.rb
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- ".gitignore"
|
51
|
+
- COPYING
|
52
|
+
- MANIFEST
|
53
|
+
- README
|
54
|
+
- Rakefile
|
55
|
+
- ext/timeout_ext/.gitignore
|
56
|
+
- ext/timeout_ext/ccan-bits.c
|
57
|
+
- ext/timeout_ext/ccan/array_size/LICENSE
|
58
|
+
- ext/timeout_ext/ccan/array_size/_info
|
59
|
+
- ext/timeout_ext/ccan/array_size/array_size.h
|
60
|
+
- ext/timeout_ext/ccan/build_assert/LICENSE
|
61
|
+
- ext/timeout_ext/ccan/build_assert/_info
|
62
|
+
- ext/timeout_ext/ccan/build_assert/build_assert.h
|
63
|
+
- ext/timeout_ext/ccan/check_type/LICENSE
|
64
|
+
- ext/timeout_ext/ccan/check_type/_info
|
65
|
+
- ext/timeout_ext/ccan/check_type/check_type.h
|
66
|
+
- ext/timeout_ext/ccan/compiler/LICENSE
|
67
|
+
- ext/timeout_ext/ccan/compiler/_info
|
68
|
+
- ext/timeout_ext/ccan/compiler/compiler.h
|
69
|
+
- ext/timeout_ext/ccan/container_of/LICENSE
|
70
|
+
- ext/timeout_ext/ccan/container_of/_info
|
71
|
+
- ext/timeout_ext/ccan/container_of/container_of.h
|
72
|
+
- ext/timeout_ext/ccan/ilog/LICENSE
|
73
|
+
- ext/timeout_ext/ccan/ilog/_info
|
74
|
+
- ext/timeout_ext/ccan/ilog/ilog.c
|
75
|
+
- ext/timeout_ext/ccan/ilog/ilog.h
|
76
|
+
- ext/timeout_ext/ccan/list/LICENSE
|
77
|
+
- ext/timeout_ext/ccan/list/_info
|
78
|
+
- ext/timeout_ext/ccan/list/list.h
|
79
|
+
- ext/timeout_ext/ccan/str/LICENSE
|
80
|
+
- ext/timeout_ext/ccan/str/_info
|
81
|
+
- ext/timeout_ext/ccan/str/str.h
|
82
|
+
- ext/timeout_ext/ccan/str/str_debug.h
|
83
|
+
- ext/timeout_ext/ccan/time/LICENSE
|
84
|
+
- ext/timeout_ext/ccan/time/_info
|
85
|
+
- ext/timeout_ext/ccan/time/time.c
|
86
|
+
- ext/timeout_ext/ccan/time/time.h
|
87
|
+
- ext/timeout_ext/ccan/timer/LICENSE
|
88
|
+
- ext/timeout_ext/ccan/timer/_info
|
89
|
+
- ext/timeout_ext/ccan/timer/design.txt
|
90
|
+
- ext/timeout_ext/ccan/timer/timer.c
|
91
|
+
- ext/timeout_ext/ccan/timer/timer.h
|
92
|
+
- ext/timeout_ext/depend
|
93
|
+
- ext/timeout_ext/extconf.rb
|
94
|
+
- ext/timeout_ext/licenses/BSD-MIT
|
95
|
+
- ext/timeout_ext/licenses/CC0
|
96
|
+
- ext/timeout_ext/licenses/LGPL-2.1
|
97
|
+
- ext/timeout_ext/missing/stdbool/stdbool.h
|
98
|
+
- ext/timeout_ext/timeout_ext.c
|
99
|
+
- test/test_timeout_ext.rb
|
100
|
+
- timeout_ext.gemspec
|
101
|
+
homepage: https://80x24.org/timeout_ext.git
|
102
|
+
licenses:
|
103
|
+
- LGPL-2.1+
|
104
|
+
metadata: {}
|
105
|
+
post_install_message:
|
106
|
+
rdoc_options: []
|
107
|
+
require_paths:
|
108
|
+
- lib
|
109
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
requirements: []
|
120
|
+
rubyforge_project:
|
121
|
+
rubygems_version: 3.0.0.beta1
|
122
|
+
signing_key:
|
123
|
+
specification_version: 4
|
124
|
+
summary: enhancement to timeout.rb in the Ruby stdlib
|
125
|
+
test_files:
|
126
|
+
- test/test_timeout_ext.rb
|