concurrent-ruby 0.7.0.rc0-x86-mingw32 → 0.7.0.rc1-x86-mingw32

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.
Files changed (31) hide show
  1. checksums.yaml +8 -8
  2. data/README.md +13 -8
  3. data/lib/1.9/concurrent_ruby_ext.so +0 -0
  4. data/lib/2.0/concurrent_ruby_ext.so +0 -0
  5. data/lib/concurrent.rb +0 -1
  6. data/lib/concurrent/actress.rb +10 -6
  7. data/lib/concurrent/actress/core.rb +1 -1
  8. data/lib/concurrent/async.rb +39 -74
  9. data/lib/concurrent/atomic.rb +21 -1
  10. data/lib/concurrent/atomic_reference/concurrent_update_error.rb +1 -0
  11. data/lib/concurrent/atomic_reference/direct_update.rb +22 -0
  12. data/lib/concurrent/atomic_reference/jruby.rb +2 -0
  13. data/lib/concurrent/atomic_reference/mutex_atomic.rb +36 -6
  14. data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +8 -7
  15. data/lib/concurrent/atomic_reference/rbx.rb +7 -4
  16. data/lib/concurrent/atomic_reference/ruby.rb +2 -0
  17. data/lib/concurrent/executor/executor.rb +118 -70
  18. data/lib/concurrent/executor/immediate_executor.rb +50 -1
  19. data/lib/concurrent/executor/java_fixed_thread_pool.rb +14 -6
  20. data/lib/concurrent/executor/java_single_thread_executor.rb +1 -0
  21. data/lib/concurrent/executor/java_thread_pool_executor.rb +3 -10
  22. data/lib/concurrent/executor/per_thread_executor.rb +80 -4
  23. data/lib/concurrent/executor/ruby_cached_thread_pool.rb +1 -1
  24. data/lib/concurrent/executor/ruby_fixed_thread_pool.rb +4 -4
  25. data/lib/concurrent/executor/ruby_single_thread_executor.rb +1 -0
  26. data/lib/concurrent/executor/ruby_thread_pool_executor.rb +2 -0
  27. data/lib/concurrent/executor/serialized_execution.rb +23 -0
  28. data/lib/concurrent/version.rb +1 -1
  29. metadata +2 -4
  30. data/lib/concurrent/atomic_reference/delegated_update.rb +0 -28
  31. data/lib/concurrent/supervisor.rb +0 -343
@@ -1,24 +1,25 @@
1
1
  module Concurrent
2
2
 
3
+ # Special "compare and set" handling of numeric values.
3
4
  module AtomicNumericCompareAndSetWrapper
4
- #alias _compare_and_set compare_and_set
5
5
 
6
- def compare_and_set(expected, new)
7
- if expected.kind_of? Numeric
6
+ # @!macro atomic_reference_method_compare_and_set
7
+ def compare_and_set(old_value, new_value)
8
+ if old_value.kind_of? Numeric
8
9
  while true
9
10
  old = get
10
11
 
11
12
  return false unless old.kind_of? Numeric
12
13
 
13
- return false unless old == expected
14
+ return false unless old == old_value
14
15
 
15
- result = _compare_and_set(old, new)
16
+ result = _compare_and_set(old, new_value)
16
17
  return result if result
17
18
  end
18
19
  else
19
- _compare_and_set(expected, new)
20
+ _compare_and_set(old_value, new_value)
20
21
  end
21
22
  end
22
- alias compare_and_swap compare_and_set
23
+ alias_method :compare_and_swap, :compare_and_set
23
24
  end
24
25
  end
@@ -3,14 +3,17 @@ require 'concurrent/atomic_reference/numeric_cas_wrapper'
3
3
 
4
4
  module Concurrent
5
5
 
6
- # extend Rubinius's version adding aliases and numeric logic
6
+ # @!macro atomic_reference
7
+ #
8
+ # @note Extends `Rubinius::AtomicReference` version adding aliases
9
+ # and numeric logic.
7
10
  class RbxAtomic < Rubinius::AtomicReference
8
11
  alias _compare_and_set compare_and_set
9
12
  include Concurrent::AtomicDirectUpdate
10
13
  include Concurrent::AtomicNumericCompareAndSetWrapper
11
14
 
12
- alias value get
13
- alias value= set
14
- alias swap get_and_set
15
+ alias_method :value, :get
16
+ alias_method :value=, :set
17
+ alias_method :swap, :get_and_set
15
18
  end
16
19
  end
@@ -9,6 +9,8 @@ require 'concurrent/atomic_reference/direct_update'
9
9
  require 'concurrent/atomic_reference/numeric_cas_wrapper'
10
10
 
11
11
  module Concurrent
12
+
13
+ # @!macro atomic_reference
12
14
  class CAtomic
13
15
  include Concurrent::AtomicDirectUpdate
14
16
  include Concurrent::AtomicNumericCompareAndSetWrapper
@@ -5,25 +5,76 @@ require 'concurrent/atomic/event'
5
5
  module Concurrent
6
6
 
7
7
  module Executor
8
+
9
+ # @!macro [attach] executor_module_method_can_overflow_question
10
+ #
11
+ # Does the task queue have a maximum size?
12
+ #
13
+ # @return [Boolean] True if the task queue has a maximum size else false.
14
+ #
15
+ # @note Always returns `false`
8
16
  def can_overflow?
9
17
  false
10
18
  end
19
+
20
+ # @!macro [attach] executor_module_method_serialized_question
21
+ #
22
+ # Does this executor guarantee serialization of its operations?
23
+ #
24
+ # @return [Boolean] True if the executor guarantees that all operations
25
+ # will be post in the order they are received and no two operations may
26
+ # occur simultaneously. Else false.
27
+ #
28
+ # @note Always returns `false`
29
+ def serialized?
30
+ false
31
+ end
32
+ end
33
+
34
+ # Indicates that the including `Executor` or `ExecutorService` guarantees
35
+ # that all operations will occur in the order they are post and that no
36
+ # two operations may occur simultaneously. This module provides no
37
+ # functionality and provides no guarantees. That is the responsibility
38
+ # of the including class. This module exists solely to allow the including
39
+ # object to be interrogated for its serialization status.
40
+ #
41
+ # @example
42
+ # class Foo
43
+ # include Concurrent::SerialExecutor
44
+ # end
45
+ #
46
+ # foo = Foo.new
47
+ #
48
+ # foo.is_a? Concurrent::Executor #=> true
49
+ # foo.is_a? Concurrent::SerialExecutor #=> true
50
+ # foo.serialized? #=> true
51
+ module SerialExecutor
52
+ include Executor
53
+
54
+ # @!macro executor_module_method_serialized_question
55
+ #
56
+ # @note Always returns `true`
57
+ def serialized?
58
+ true
59
+ end
11
60
  end
12
61
 
13
62
  module RubyExecutor
14
63
  include Executor
15
64
  include Logging
16
65
 
17
- # Submit a task to the executor for asynchronous processing.
66
+ # @!macro [attach] executor_method_post
67
+ #
68
+ # Submit a task to the executor for asynchronous processing.
18
69
  #
19
- # @param [Array] args zero or more arguments to be passed to the task
70
+ # @param [Array] args zero or more arguments to be passed to the task
20
71
  #
21
- # @yield the asynchronous task to perform
72
+ # @yield the asynchronous task to perform
22
73
  #
23
- # @return [Boolean] `true` if the task is queued, `false` if the executor
24
- # is not running
74
+ # @return [Boolean] `true` if the task is queued, `false` if the executor
75
+ # is not running
25
76
  #
26
- # @raise [ArgumentError] if no task is given
77
+ # @raise [ArgumentError] if no task is given
27
78
  def post(*args, &task)
28
79
  raise ArgumentError.new('no block given') unless block_given?
29
80
  mutex.synchronize do
@@ -33,40 +84,50 @@ module Concurrent
33
84
  end
34
85
  end
35
86
 
36
- # Submit a task to the executor for asynchronous processing.
87
+ # @!macro [attach] executor_method_left_shift
37
88
  #
38
- # @param [Proc] task the asynchronous task to perform
89
+ # Submit a task to the executor for asynchronous processing.
39
90
  #
40
- # @return [self] returns itself
91
+ # @param [Proc] task the asynchronous task to perform
92
+ #
93
+ # @return [self] returns itself
41
94
  def <<(task)
42
95
  post(&task)
43
96
  self
44
97
  end
45
98
 
46
- # Is the executor running?
99
+ # @!macro [attach] executor_method_running_question
100
+ #
101
+ # Is the executor running?
47
102
  #
48
- # @return [Boolean] `true` when running, `false` when shutting down or shutdown
103
+ # @return [Boolean] `true` when running, `false` when shutting down or shutdown
49
104
  def running?
50
105
  ! stop_event.set?
51
106
  end
52
107
 
53
- # Is the executor shuttingdown?
108
+ # @!macro [attach] executor_method_shuttingdown_question
109
+ #
110
+ # Is the executor shuttingdown?
54
111
  #
55
- # @return [Boolean] `true` when not running and not shutdown, else `false`
112
+ # @return [Boolean] `true` when not running and not shutdown, else `false`
56
113
  def shuttingdown?
57
114
  ! (running? || shutdown?)
58
115
  end
59
116
 
60
- # Is the executor shutdown?
117
+ # @!macro [attach] executor_method_shutdown_question
61
118
  #
62
- # @return [Boolean] `true` when shutdown, `false` when shutting down or running
119
+ # Is the executor shutdown?
120
+ #
121
+ # @return [Boolean] `true` when shutdown, `false` when shutting down or running
63
122
  def shutdown?
64
123
  stopped_event.set?
65
124
  end
66
125
 
67
- # Begin an orderly shutdown. Tasks already in the queue will be executed,
68
- # but no new tasks will be accepted. Has no additional effect if the
69
- # thread pool is not running.
126
+ # @!macro [attach] executor_method_shutdown
127
+ #
128
+ # Begin an orderly shutdown. Tasks already in the queue will be executed,
129
+ # but no new tasks will be accepted. Has no additional effect if the
130
+ # thread pool is not running.
70
131
  def shutdown
71
132
  mutex.synchronize do
72
133
  break unless running?
@@ -76,10 +137,12 @@ module Concurrent
76
137
  true
77
138
  end
78
139
 
79
- # Begin an immediate shutdown. In-progress tasks will be allowed to
80
- # complete but enqueued tasks will be dismissed and no new tasks
81
- # will be accepted. Has no additional effect if the thread pool is
82
- # not running.
140
+ # @!macro [attach] executor_method_kill
141
+ #
142
+ # Begin an immediate shutdown. In-progress tasks will be allowed to
143
+ # complete but enqueued tasks will be dismissed and no new tasks
144
+ # will be accepted. Has no additional effect if the thread pool is
145
+ # not running.
83
146
  def kill
84
147
  mutex.synchronize do
85
148
  break if shutdown?
@@ -90,15 +153,17 @@ module Concurrent
90
153
  true
91
154
  end
92
155
 
93
- # Block until executor shutdown is complete or until `timeout` seconds have
94
- # passed.
156
+ # @!macro [attach] executor_method_wait_for_termination
95
157
  #
96
- # @note Does not initiate shutdown or termination. Either `shutdown` or `kill`
97
- # must be called before this method (or on another thread).
158
+ # Block until executor shutdown is complete or until `timeout` seconds have
159
+ # passed.
98
160
  #
99
- # @param [Integer] timeout the maximum number of seconds to wait for shutdown to complete
161
+ # @note Does not initiate shutdown or termination. Either `shutdown` or `kill`
162
+ # must be called before this method (or on another thread).
100
163
  #
101
- # @return [Boolean] `true` if shutdown complete or false on `timeout`
164
+ # @param [Integer] timeout the maximum number of seconds to wait for shutdown to complete
165
+ #
166
+ # @return [Boolean] `true` if shutdown complete or false on `timeout`
102
167
  def wait_for_termination(timeout = nil)
103
168
  stopped_event.wait(timeout)
104
169
  end
@@ -107,20 +172,33 @@ module Concurrent
107
172
 
108
173
  attr_reader :mutex, :stop_event, :stopped_event
109
174
 
175
+ # @!macro [attach] executor_method_init_executor
176
+ #
177
+ # Initialize the executor by creating and initializing all the
178
+ # internal synchronization objects.
110
179
  def init_executor
111
180
  @mutex = Mutex.new
112
181
  @stop_event = Event.new
113
182
  @stopped_event = Event.new
114
183
  end
115
184
 
185
+ # @!macro [attach] executor_method_execute
116
186
  def execute(*args, &task)
117
187
  raise NotImplementedError
118
188
  end
119
189
 
190
+ # @!macro [attach] executor_method_shutdown_execution
191
+ #
192
+ # Callback method called when an orderly shutdown has completed.
193
+ # The default behavior is to signal all waiting threads.
120
194
  def shutdown_execution
121
195
  stopped_event.set
122
196
  end
123
197
 
198
+ # @!macro [attach] executor_method_kill_execution
199
+ #
200
+ # Callback method called when the executor has been killed.
201
+ # The default behavior is to do nothing.
124
202
  def kill_execution
125
203
  # do nothing
126
204
  end
@@ -130,49 +208,34 @@ module Concurrent
130
208
 
131
209
  module JavaExecutor
132
210
  include Executor
211
+ java_import 'java.lang.Runnable'
133
212
 
134
- # Submit a task to the executor for asynchronous processing.
135
- #
136
- # @param [Array] args zero or more arguments to be passed to the task
137
- #
138
- # @yield the asynchronous task to perform
139
- #
140
- # @return [Boolean] `true` if the task is queued, `false` if the executor
141
- # is not running
142
- #
143
- # @raise [ArgumentError] if no task is given
213
+ # @!macro executor_method_post
144
214
  def post(*args)
145
215
  raise ArgumentError.new('no block given') unless block_given?
146
216
  if running?
147
- @executor.submit{ yield(*args) }
217
+ executor_submit = @executor.java_method(:submit, [Runnable.java_class])
218
+ executor_submit.call { yield(*args) }
148
219
  true
149
220
  else
150
221
  false
151
222
  end
152
- rescue Java::JavaUtilConcurrent::RejectedExecutionException => ex
223
+ rescue Java::JavaUtilConcurrent::RejectedExecutionException
153
224
  raise RejectedExecutionError
154
225
  end
155
226
 
156
- # Submit a task to the executor for asynchronous processing.
157
- #
158
- # @param [Proc] task the asynchronous task to perform
159
- #
160
- # @return [self] returns itself
227
+ # @!macro executor_method_left_shift
161
228
  def <<(task)
162
229
  post(&task)
163
230
  self
164
231
  end
165
232
 
166
- # Is the executor running?
167
- #
168
- # @return [Boolean] `true` when running, `false` when shutting down or shutdown
233
+ # @!macro executor_method_running_question
169
234
  def running?
170
235
  ! (shuttingdown? || shutdown?)
171
236
  end
172
237
 
173
- # Is the executor shuttingdown?
174
- #
175
- # @return [Boolean] `true` when not running and not shutdown, else `false`
238
+ # @!macro executor_method_shuttingdown_question
176
239
  def shuttingdown?
177
240
  if @executor.respond_to? :isTerminating
178
241
  @executor.isTerminating
@@ -181,38 +244,23 @@ module Concurrent
181
244
  end
182
245
  end
183
246
 
184
- # Is the executor shutdown?
185
- #
186
- # @return [Boolean] `true` when shutdown, `false` when shutting down or running
247
+ # @!macro executor_method_shutdown_question
187
248
  def shutdown?
188
249
  @executor.isShutdown || @executor.isTerminated
189
250
  end
190
251
 
191
- # Block until executor shutdown is complete or until `timeout` seconds have
192
- # passed.
193
- #
194
- # @note Does not initiate shutdown or termination. Either `shutdown` or `kill`
195
- # must be called before this method (or on another thread).
196
- #
197
- # @param [Integer] timeout the maximum number of seconds to wait for shutdown to complete
198
- #
199
- # @return [Boolean] `true` if shutdown complete or false on `timeout`
252
+ # @!macro executor_method_wait_for_termination
200
253
  def wait_for_termination(timeout)
201
254
  @executor.awaitTermination(1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS)
202
255
  end
203
256
 
204
- # Begin an orderly shutdown. Tasks already in the queue will be executed,
205
- # but no new tasks will be accepted. Has no additional effect if the
206
- # executor is not running.
257
+ # @!macro executor_method_shutdown
207
258
  def shutdown
208
259
  @executor.shutdown
209
260
  nil
210
261
  end
211
262
 
212
- # Begin an immediate shutdown. In-progress tasks will be allowed to
213
- # complete but enqueued tasks will be dismissed and no new tasks
214
- # will be accepted. Has no additional effect if the executor is
215
- # not running.
263
+ # @!macro executor_method_kill
216
264
  def kill
217
265
  @executor.shutdownNow
218
266
  nil
@@ -1,16 +1,65 @@
1
+ require 'concurrent/atomic/event'
2
+ require 'concurrent/executor/executor'
3
+
1
4
  module Concurrent
5
+
6
+ # An executor service which runs all operations on the current thread,
7
+ # blocking as necessary. Operations are performed in the order they are
8
+ # received and no two operations can be performed simultaneously.
9
+ #
10
+ # This executor service exists mainly for testing an debugging. When used
11
+ # it immediately runs every `#post` operation on the current thread, blocking
12
+ # that thread until the operation is complete. This can be very beneficial
13
+ # during testing because it makes all operations deterministic.
14
+ #
15
+ # @note Intended for use primarily in testing and debugging.
2
16
  class ImmediateExecutor
3
- include Executor
17
+ include SerialExecutor
18
+
19
+ # Creates a new executor
20
+ def initialize
21
+ @stopped = Concurrent::Event.new
22
+ end
4
23
 
24
+ # @!macro executor_method_post
5
25
  def post(*args, &task)
6
26
  raise ArgumentError.new('no block given') unless block_given?
27
+ return false unless running?
7
28
  task.call(*args)
8
29
  true
9
30
  end
10
31
 
32
+ # @!macro executor_method_left_shift
11
33
  def <<(task)
12
34
  post(&task)
13
35
  self
14
36
  end
37
+
38
+ # @!macro executor_method_running_question
39
+ def running?
40
+ ! shutdown?
41
+ end
42
+
43
+ # @!macro executor_method_shuttingdown_question
44
+ def shuttingdown?
45
+ false
46
+ end
47
+
48
+ # @!macro executor_method_shutdown_question
49
+ def shutdown?
50
+ @stopped.set?
51
+ end
52
+
53
+ # @!macro executor_method_shutdown
54
+ def shutdown
55
+ @stopped.set
56
+ true
57
+ end
58
+ alias_method :kill, :shutdown
59
+
60
+ # @!macro executor_method_wait_for_termination
61
+ def wait_for_termination(timeout = nil)
62
+ @stopped.wait(timeout)
63
+ end
15
64
  end
16
65
  end