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 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
- instance_variable_defined? :@exception
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
- @exception
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
- instance_variable_defined? :@value
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
- begin
46
- @value = @block.call
47
- rescue Exception => e
48
- @exception = e
54
+ @mutex.synchronize {
55
+ begin
56
+ @value = @block.call
57
+ rescue Exception => e
58
+ @exception = e
49
59
 
50
- raise
51
- end
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/promise'
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
- Thread.new {
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
- instance_variable_defined? :@exception
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
- @exception
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
- instance_variable_defined? :@value
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
- else
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
- @value = value
84
-
85
- if cond?
86
- mutex.synchronize {
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
@@ -50,7 +50,7 @@ class Thread::Pool
50
50
  @running = true
51
51
  @started_at = Time.now
52
52
 
53
- pool.__send__.wake_up_timeout
53
+ pool.__send__ :wake_up_timeout
54
54
 
55
55
  begin
56
56
  @block.call(*@arguments)
@@ -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
- instance_variable_defined? :@value
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
- @value = value
27
-
28
- if cond?
29
- mutex.synchronize {
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
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new {|s|
2
2
  s.name = 'thread'
3
- s.version = '0.0.3'
3
+ s.version = '0.0.4'
4
4
  s.author = 'meh.'
5
5
  s.email = 'meh@schizofreni.co'
6
6
  s.homepage = 'http://github.com/meh/ruby-thread'
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.3
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-02-25 00:00:00.000000000 Z
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.