thread 0.0.3 → 0.0.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/lib/thread/delay.rb +20 -9
- data/lib/thread/future.rb +44 -31
- data/lib/thread/pool.rb +1 -1
- data/lib/thread/promise.rb +17 -25
- data/thread.gemspec +1 -1
- metadata +2 -2
data/lib/thread/delay.rb
CHANGED
@@ -11,23 +11,32 @@
|
|
11
11
|
# A delay is an object that incapsulates a block which is called upon
|
12
12
|
# value retrieval, and its result cached.
|
13
13
|
class Thread::Delay
|
14
|
+
# Create a delay with the passed block.
|
14
15
|
def initialize (&block)
|
16
|
+
@mutex = Mutex.new
|
17
|
+
|
15
18
|
@block = block
|
16
19
|
end
|
17
20
|
|
18
21
|
# Check if an exception has been raised.
|
19
22
|
def exception?
|
20
|
-
|
23
|
+
@mutex.synchronize {
|
24
|
+
instance_variable_defined? :@exception
|
25
|
+
}
|
21
26
|
end
|
22
27
|
|
23
28
|
# Return the raised exception.
|
24
29
|
def exception
|
25
|
-
@
|
30
|
+
@mutex.synchronize {
|
31
|
+
@exception
|
32
|
+
}
|
26
33
|
end
|
27
34
|
|
28
35
|
# Check if the delay has been called.
|
29
36
|
def delivered?
|
30
|
-
|
37
|
+
@mutex.synchronize {
|
38
|
+
instance_variable_defined? :@value
|
39
|
+
}
|
31
40
|
end
|
32
41
|
|
33
42
|
alias realized? delivered?
|
@@ -42,13 +51,15 @@ class Thread::Delay
|
|
42
51
|
|
43
52
|
return @value if realized?
|
44
53
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
54
|
+
@mutex.synchronize {
|
55
|
+
begin
|
56
|
+
@value = @block.call
|
57
|
+
rescue Exception => e
|
58
|
+
@exception = e
|
49
59
|
|
50
|
-
|
51
|
-
|
60
|
+
raise
|
61
|
+
end
|
62
|
+
}
|
52
63
|
end
|
53
64
|
|
54
65
|
alias ~ value
|
data/lib/thread/future.rb
CHANGED
@@ -8,14 +8,20 @@
|
|
8
8
|
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
9
9
|
#++
|
10
10
|
|
11
|
-
require 'thread
|
11
|
+
require 'thread'
|
12
12
|
|
13
13
|
# A future is an object that incapsulates a block which is called in a
|
14
14
|
# different thread, upon retrieval the caller gets blocked until the block has
|
15
15
|
# finished running, and its result is returned and cached.
|
16
16
|
class Thread::Future
|
17
|
+
Cancel = Class.new(Exception)
|
18
|
+
|
19
|
+
# Create a future with the passed block.
|
17
20
|
def initialize (&block)
|
18
|
-
|
21
|
+
@mutex = Mutex.new
|
22
|
+
@cond = ConditionVariable.new
|
23
|
+
|
24
|
+
@thread = Thread.new {
|
19
25
|
begin
|
20
26
|
deliver block.call
|
21
27
|
rescue Exception => e
|
@@ -28,47 +34,69 @@ class Thread::Future
|
|
28
34
|
|
29
35
|
# Check if an exception has been raised.
|
30
36
|
def exception?
|
31
|
-
|
37
|
+
@mutex.synchronize {
|
38
|
+
instance_variable_defined? :@exception
|
39
|
+
}
|
32
40
|
end
|
33
41
|
|
34
42
|
# Return the raised exception.
|
35
43
|
def exception
|
36
|
-
@
|
44
|
+
@mutex.synchronize {
|
45
|
+
@exception
|
46
|
+
}
|
37
47
|
end
|
38
48
|
|
39
49
|
# Check if the future has been called.
|
40
50
|
def delivered?
|
41
|
-
|
51
|
+
@mutex.synchronize {
|
52
|
+
instance_variable_defined? :@value
|
53
|
+
}
|
42
54
|
end
|
43
55
|
|
44
56
|
alias realized? delivered?
|
45
57
|
|
58
|
+
# Cancel the future, {#value} will yield a Cancel exception
|
59
|
+
def cancel
|
60
|
+
return if delivered?
|
61
|
+
|
62
|
+
@mutex.synchronize {
|
63
|
+
@thread.raise Cancel.new('future cancelled')
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
# Check if the future has been cancelled
|
68
|
+
def cancelled?
|
69
|
+
@mutex.synchronize {
|
70
|
+
@exception.is_a? Cancel
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
46
74
|
# Get the value of the future, if it's not finished running this call will block.
|
47
75
|
#
|
48
76
|
# In case the block raises an exception, it will be raised, the exception is cached
|
49
77
|
# and will be raised every time you access the value.
|
50
|
-
def value
|
78
|
+
def value (timeout = nil)
|
51
79
|
raise @exception if exception?
|
52
80
|
|
53
81
|
return @value if delivered?
|
54
82
|
|
55
|
-
mutex.synchronize {
|
56
|
-
cond.wait(mutex)
|
83
|
+
@mutex.synchronize {
|
84
|
+
@cond.wait(@mutex, *timeout)
|
57
85
|
}
|
58
86
|
|
59
87
|
if exception?
|
60
88
|
raise @exception
|
61
|
-
|
62
|
-
@value
|
89
|
+
elsif delivered?
|
90
|
+
return @value
|
63
91
|
end
|
64
92
|
end
|
65
93
|
|
66
94
|
alias ~ value
|
67
95
|
|
68
96
|
# Do the same as {#value}, but return nil in case of exception.
|
69
|
-
def value!
|
97
|
+
def value! (timeout = nil)
|
70
98
|
begin
|
71
|
-
value
|
99
|
+
value(timeout)
|
72
100
|
rescue Exception
|
73
101
|
nil
|
74
102
|
end
|
@@ -80,28 +108,13 @@ private
|
|
80
108
|
def deliver (value)
|
81
109
|
return if delivered?
|
82
110
|
|
83
|
-
@
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
cond.broadcast
|
88
|
-
}
|
89
|
-
end
|
111
|
+
@mutex.synchronize {
|
112
|
+
@value = value
|
113
|
+
@cond.broadcast
|
114
|
+
}
|
90
115
|
|
91
116
|
self
|
92
117
|
end
|
93
|
-
|
94
|
-
def cond?
|
95
|
-
instance_variable_defined? :@cond
|
96
|
-
end
|
97
|
-
|
98
|
-
def cond
|
99
|
-
@cond ||= ConditionVariable.new
|
100
|
-
end
|
101
|
-
|
102
|
-
def mutex
|
103
|
-
@mutex ||= Mutex.new
|
104
|
-
end
|
105
118
|
end
|
106
119
|
|
107
120
|
module Kernel
|
data/lib/thread/pool.rb
CHANGED
data/lib/thread/promise.rb
CHANGED
@@ -12,9 +12,17 @@ require 'thread'
|
|
12
12
|
|
13
13
|
# A promise is an object that lets you wait for a value to be delivered to it.
|
14
14
|
class Thread::Promise
|
15
|
+
# Create a promise.
|
16
|
+
def initialize
|
17
|
+
@mutex = Mutex.new
|
18
|
+
@cond = ConditionVariable.new
|
19
|
+
end
|
20
|
+
|
15
21
|
# Check if a value has been delivered.
|
16
22
|
def delivered?
|
17
|
-
|
23
|
+
@mutex.synchronize {
|
24
|
+
instance_variable_defined? :@value
|
25
|
+
}
|
18
26
|
end
|
19
27
|
|
20
28
|
alias realized? delivered?
|
@@ -23,13 +31,10 @@ class Thread::Promise
|
|
23
31
|
def deliver (value)
|
24
32
|
return if delivered?
|
25
33
|
|
26
|
-
@
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
cond.broadcast
|
31
|
-
}
|
32
|
-
end
|
34
|
+
@mutex.synchronize {
|
35
|
+
@value = value
|
36
|
+
@cond.broadcast
|
37
|
+
}
|
33
38
|
|
34
39
|
self
|
35
40
|
end
|
@@ -38,30 +43,17 @@ class Thread::Promise
|
|
38
43
|
|
39
44
|
# Get the value that's been delivered, if none has been delivered yet the call
|
40
45
|
# will block until one is delivered.
|
41
|
-
def value
|
46
|
+
def value (timeout = nil)
|
42
47
|
return @value if delivered?
|
43
48
|
|
44
|
-
mutex.synchronize {
|
45
|
-
cond.wait(mutex)
|
49
|
+
@mutex.synchronize {
|
50
|
+
@cond.wait(@mutex, *timeout)
|
46
51
|
}
|
47
52
|
|
48
|
-
@value
|
53
|
+
return @value if delivered?
|
49
54
|
end
|
50
55
|
|
51
56
|
alias ~ value
|
52
|
-
|
53
|
-
private
|
54
|
-
def cond?
|
55
|
-
instance_variable_defined? :@cond
|
56
|
-
end
|
57
|
-
|
58
|
-
def cond
|
59
|
-
@cond ||= ConditionVariable.new
|
60
|
-
end
|
61
|
-
|
62
|
-
def mutex
|
63
|
-
@mutex ||= Mutex.new
|
64
|
-
end
|
65
57
|
end
|
66
58
|
|
67
59
|
module Kernel
|
data/thread.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thread
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-03-01 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Includes a thread pool, message passing capabilities, a recursive mutex,
|
15
15
|
promise, future and delay.
|