splib 1.3 → 1.4
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.
- data/CHANGELOG +5 -0
- data/lib/splib.rb +1 -0
- data/lib/splib/Float.rb +18 -0
- data/lib/splib/Monitor.rb +63 -35
- data/splib.gemspec +1 -1
- data/tests/cases/Float.rb +20 -0
- data/tests/cases/Monitor.rb +14 -0
- metadata +10 -9
data/CHANGELOG
CHANGED
data/lib/splib.rb
CHANGED
data/lib/splib/Float.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Splib
|
2
|
+
# While not a big fan of monkeypatching, I want to be
|
3
|
+
# lazy getting to this
|
4
|
+
class ::Float
|
5
|
+
def within_delta?(args={})
|
6
|
+
raise ArgumentError.new('Missing required argument: :expected') unless args[:expected]
|
7
|
+
raise ArgumentError.new('Missing required argument: :delta') unless args[:delta]
|
8
|
+
e = args[:expected].to_f
|
9
|
+
d = args[:delta].to_f
|
10
|
+
mult = 0
|
11
|
+
if(pos = d.to_s.index('.'))
|
12
|
+
mult = (d.to_s.length - (pos + 1))
|
13
|
+
end
|
14
|
+
mult = 10 ** mult
|
15
|
+
((e*mult) - (self*mult)).abs <= (d*mult)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/splib/Monitor.rb
CHANGED
@@ -7,12 +7,27 @@ module Splib
|
|
7
7
|
@threads = []
|
8
8
|
@locks = []
|
9
9
|
@lock_owner = nil
|
10
|
+
@timers = {}
|
10
11
|
end
|
11
12
|
# timeout:: Wait for given amount of time
|
12
13
|
# Park a thread here
|
13
14
|
def wait(timeout=nil)
|
15
|
+
if(timeout)
|
16
|
+
timout = timeout.to_f
|
17
|
+
@timers[Thread.current] = Thread.new(Thread.current) do |t|
|
18
|
+
sleep(timeout)
|
19
|
+
t.wakeup
|
20
|
+
end
|
21
|
+
end
|
14
22
|
@threads << Thread.current
|
15
23
|
Thread.stop
|
24
|
+
@threads.delete(Thread.current)
|
25
|
+
if(timeout)
|
26
|
+
if(@timers[Thread.current].alive?)
|
27
|
+
@timers[Thread.current].kill
|
28
|
+
end
|
29
|
+
@timers.delete(Thread.current)
|
30
|
+
end
|
16
31
|
true
|
17
32
|
end
|
18
33
|
# Park thread while block is true
|
@@ -29,19 +44,19 @@ module Splib
|
|
29
44
|
end
|
30
45
|
# Wake up earliest thread
|
31
46
|
def signal
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
47
|
+
synchronize do
|
48
|
+
t = @threads.shift
|
49
|
+
t.wakeup if t && t.alive?
|
50
|
+
end
|
36
51
|
end
|
37
52
|
# Wake up all threads
|
38
53
|
def broadcast
|
39
|
-
|
40
|
-
|
41
|
-
|
54
|
+
synchronize do
|
55
|
+
@threads.each do |t|
|
56
|
+
t.wakeup if t.alive?
|
57
|
+
end
|
58
|
+
@threads.clear
|
42
59
|
end
|
43
|
-
@threads.clear
|
44
|
-
unlock
|
45
60
|
end
|
46
61
|
# Number of threads waiting
|
47
62
|
def waiters
|
@@ -49,38 +64,51 @@ module Splib
|
|
49
64
|
end
|
50
65
|
# Lock the monitor
|
51
66
|
def lock
|
52
|
-
stop
|
53
|
-
Thread.exclusive do
|
54
|
-
unless(@locks.empty?)
|
55
|
-
@locks << Thread.current
|
56
|
-
stop = true
|
57
|
-
else
|
58
|
-
@lock_owner = Thread.current
|
59
|
-
end
|
60
|
-
end
|
61
|
-
Thread.stop if stop
|
67
|
+
Thread.stop if Thread.exclusive{ do_lock }
|
62
68
|
end
|
63
69
|
# Unlock the monitor
|
64
70
|
def unlock
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
@locks.delete{|t|!t.alive?}
|
71
|
-
@lock_owner = @locks.shift
|
72
|
-
@lock_owner.wakeup
|
73
|
-
else
|
74
|
-
@lock_owner = nil
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
71
|
+
Thread.exclusive{ do_unlock }
|
72
|
+
end
|
73
|
+
# Is monitor locked
|
74
|
+
def locked?
|
75
|
+
@locks.size > 0
|
78
76
|
end
|
79
77
|
# Lock the monitor, execute block and unlock the monitor
|
80
78
|
def synchronize
|
81
|
-
|
82
|
-
|
83
|
-
|
79
|
+
result = nil
|
80
|
+
Thread.exclusive do
|
81
|
+
do_lock
|
82
|
+
result = yield
|
83
|
+
do_unlock
|
84
|
+
end
|
85
|
+
result
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def do_lock
|
91
|
+
stop = false
|
92
|
+
unless(@locks.empty?)
|
93
|
+
@locks << Thread.current
|
94
|
+
stop = true
|
95
|
+
else
|
96
|
+
@lock_owner = Thread.current
|
97
|
+
end
|
98
|
+
stop
|
99
|
+
end
|
100
|
+
|
101
|
+
def do_unlock
|
102
|
+
unless(@lock_owner == Thread.current)
|
103
|
+
raise ThreadError.new("Thread #{Thread.current} is not the current owner: #{@lock_owner}")
|
104
|
+
end
|
105
|
+
unless(@locks.empty?)
|
106
|
+
@locks.delete{|t|!t.alive?}
|
107
|
+
@lock_owner = @locks.shift
|
108
|
+
@lock_owner.wakeup
|
109
|
+
else
|
110
|
+
@lock_owner = nil
|
111
|
+
end
|
84
112
|
end
|
85
113
|
end
|
86
114
|
end
|
data/splib.gemspec
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'splib'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class FloatTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
Splib.load :Float
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_delta
|
10
|
+
t = 3.2
|
11
|
+
assert(3.204.within_delta?(:expected => t, :delta => 0.1))
|
12
|
+
assert(3.3.within_delta?(:expected => t, :delta => 0.1))
|
13
|
+
assert(3.3.within_delta?(:expected => t, :delta => 0.1))
|
14
|
+
assert(3.1.within_delta?(:expected => t, :delta => 0.1))
|
15
|
+
assert(!(3.09.within_delta?(:expected => t, :delta => 0.1)))
|
16
|
+
assert(!(3.31.within_delta?(:expected => t, :delta => 0.1)))
|
17
|
+
assert(3.0.within_delta?(:expected => 4, :delta => 1))
|
18
|
+
assert(!(3.0.within_delta?(:expected => 5, :delta => 1)))
|
19
|
+
end
|
20
|
+
end
|
data/tests/cases/Monitor.rb
CHANGED
@@ -17,6 +17,20 @@ class MonitorTest < Test::Unit::TestCase
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
def test_wait_timeout
|
21
|
+
t = []
|
22
|
+
o = []
|
23
|
+
5.times{|i| t << Thread.new{ @monitor.wait((i+1)/100.0); o << 1 } }
|
24
|
+
sleep(0.015)
|
25
|
+
assert(!t.shift.alive?)
|
26
|
+
assert_equal(1, o.size)
|
27
|
+
sleep(0.11)
|
28
|
+
assert_equal(5, o.size)
|
29
|
+
t.each do |th|
|
30
|
+
assert(!th.alive?)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
20
34
|
def test_signal
|
21
35
|
output = []
|
22
36
|
t = []
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: splib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "1.
|
4
|
+
version: "1.4"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- spox
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-13 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -23,13 +23,12 @@ extra_rdoc_files:
|
|
23
23
|
- README.rdoc
|
24
24
|
- CHANGELOG
|
25
25
|
files:
|
26
|
-
- tests
|
27
|
-
- tests/cases
|
28
26
|
- tests/cases/Array.rb
|
29
27
|
- tests/cases/PriorityQueue.rb
|
30
28
|
- tests/cases/UrlShorteners.rb
|
31
29
|
- tests/cases/Exec.rb
|
32
30
|
- tests/cases/Constants.rb
|
31
|
+
- tests/cases/Float.rb
|
33
32
|
- tests/cases/CodeReloader.rb
|
34
33
|
- tests/cases/HumanIdealRandomIterator.rb
|
35
34
|
- tests/cases/Monitor.rb
|
@@ -37,14 +36,13 @@ files:
|
|
37
36
|
- tests/run_tests.rb
|
38
37
|
- tests/samplecode2.rb
|
39
38
|
- tests/samplecode1.rb
|
40
|
-
- lib
|
41
39
|
- lib/splib.rb
|
42
|
-
- lib/splib
|
43
40
|
- lib/splib/Array.rb
|
44
41
|
- lib/splib/PriorityQueue.rb
|
45
42
|
- lib/splib/UrlShorteners.rb
|
46
43
|
- lib/splib/Exec.rb
|
47
44
|
- lib/splib/Constants.rb
|
45
|
+
- lib/splib/Float.rb
|
48
46
|
- lib/splib/CodeReloader.rb
|
49
47
|
- lib/splib/HumanIdealRandomIterator.rb
|
50
48
|
- lib/splib/Monitor.rb
|
@@ -53,8 +51,11 @@ files:
|
|
53
51
|
- LICENSE
|
54
52
|
- splib.gemspec
|
55
53
|
- README.rdoc
|
56
|
-
|
54
|
+
- splib-1.4.gem
|
55
|
+
has_rdoc: true
|
57
56
|
homepage: http://github.com/spox/splib
|
57
|
+
licenses: []
|
58
|
+
|
58
59
|
post_install_message:
|
59
60
|
rdoc_options:
|
60
61
|
- --title
|
@@ -79,9 +80,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
80
|
requirements: []
|
80
81
|
|
81
82
|
rubyforge_project:
|
82
|
-
rubygems_version: 1.3.
|
83
|
+
rubygems_version: 1.3.5
|
83
84
|
signing_key:
|
84
|
-
specification_version:
|
85
|
+
specification_version: 3
|
85
86
|
summary: Spox Library
|
86
87
|
test_files: []
|
87
88
|
|