thread 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|