concurrent-ruby 0.9.2 → 1.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -1
  3. data/README.md +67 -68
  4. data/lib/concurrent.rb +14 -1
  5. data/lib/concurrent/array.rb +38 -0
  6. data/lib/concurrent/async.rb +0 -17
  7. data/lib/concurrent/atomic/abstract_thread_local_var.rb +40 -0
  8. data/lib/concurrent/atomic/atomic_boolean.rb +81 -118
  9. data/lib/concurrent/atomic/atomic_fixnum.rb +98 -162
  10. data/lib/concurrent/atomic/atomic_reference.rb +0 -7
  11. data/lib/concurrent/atomic/count_down_latch.rb +62 -103
  12. data/lib/concurrent/atomic/cyclic_barrier.rb +2 -0
  13. data/lib/concurrent/atomic/java_count_down_latch.rb +39 -0
  14. data/lib/concurrent/atomic/java_thread_local_var.rb +50 -0
  15. data/lib/concurrent/atomic/mutex_atomic_boolean.rb +60 -0
  16. data/lib/concurrent/atomic/mutex_atomic_fixnum.rb +91 -0
  17. data/lib/concurrent/atomic/mutex_count_down_latch.rb +43 -0
  18. data/lib/concurrent/atomic/mutex_semaphore.rb +115 -0
  19. data/lib/concurrent/atomic/ruby_thread_local_var.rb +172 -0
  20. data/lib/concurrent/atomic/semaphore.rb +84 -178
  21. data/lib/concurrent/atomic/thread_local_var.rb +63 -294
  22. data/lib/concurrent/atomic_reference/mutex_atomic.rb +14 -8
  23. data/lib/concurrent/atomics.rb +0 -33
  24. data/lib/concurrent/collection/java_non_concurrent_priority_queue.rb +84 -0
  25. data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +921 -0
  26. data/lib/concurrent/collection/map/mri_map_backend.rb +66 -0
  27. data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +142 -0
  28. data/lib/concurrent/collection/map/synchronized_map_backend.rb +86 -0
  29. data/lib/concurrent/collection/non_concurrent_priority_queue.rb +143 -0
  30. data/lib/concurrent/collection/ruby_non_concurrent_priority_queue.rb +150 -0
  31. data/lib/concurrent/concern/logging.rb +1 -1
  32. data/lib/concurrent/concern/obligation.rb +0 -12
  33. data/lib/concurrent/configuration.rb +18 -148
  34. data/lib/concurrent/delay.rb +5 -4
  35. data/lib/concurrent/exchanger.rb +327 -41
  36. data/lib/concurrent/executor/abstract_executor_service.rb +134 -0
  37. data/lib/concurrent/executor/executor.rb +4 -29
  38. data/lib/concurrent/executor/executor_service.rb +23 -359
  39. data/lib/concurrent/executor/immediate_executor.rb +3 -2
  40. data/lib/concurrent/executor/java_executor_service.rb +100 -0
  41. data/lib/concurrent/executor/java_single_thread_executor.rb +3 -2
  42. data/lib/concurrent/executor/java_thread_pool_executor.rb +3 -4
  43. data/lib/concurrent/executor/ruby_executor_service.rb +72 -0
  44. data/lib/concurrent/executor/ruby_single_thread_executor.rb +7 -5
  45. data/lib/concurrent/executor/ruby_thread_pool_executor.rb +3 -11
  46. data/lib/concurrent/executor/safe_task_executor.rb +1 -1
  47. data/lib/concurrent/executor/serial_executor_service.rb +34 -0
  48. data/lib/concurrent/executor/serialized_execution.rb +8 -31
  49. data/lib/concurrent/executor/serialized_execution_delegator.rb +28 -0
  50. data/lib/concurrent/executor/simple_executor_service.rb +1 -10
  51. data/lib/concurrent/executor/timer_set.rb +4 -8
  52. data/lib/concurrent/executors.rb +13 -2
  53. data/lib/concurrent/future.rb +2 -2
  54. data/lib/concurrent/hash.rb +35 -0
  55. data/lib/concurrent/ivar.rb +9 -14
  56. data/lib/concurrent/map.rb +178 -0
  57. data/lib/concurrent/promise.rb +2 -2
  58. data/lib/concurrent/scheduled_task.rb +9 -69
  59. data/lib/concurrent/thread_safe/synchronized_delegator.rb +50 -0
  60. data/lib/concurrent/thread_safe/util.rb +23 -0
  61. data/lib/concurrent/thread_safe/util/adder.rb +71 -0
  62. data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +28 -0
  63. data/lib/concurrent/thread_safe/util/cheap_lockable.rb +115 -0
  64. data/lib/concurrent/thread_safe/util/power_of_two_tuple.rb +37 -0
  65. data/lib/concurrent/thread_safe/util/striped64.rb +236 -0
  66. data/lib/concurrent/thread_safe/util/volatile.rb +73 -0
  67. data/lib/concurrent/thread_safe/util/xor_shift_random.rb +48 -0
  68. data/lib/concurrent/timer_task.rb +3 -3
  69. data/lib/concurrent/tuple.rb +86 -0
  70. data/lib/concurrent/version.rb +2 -2
  71. metadata +37 -10
  72. data/lib/concurrent/atomic/condition.rb +0 -78
  73. data/lib/concurrent/collection/priority_queue.rb +0 -360
  74. data/lib/concurrent/utilities.rb +0 -5
  75. data/lib/concurrent/utility/timeout.rb +0 -39
  76. data/lib/concurrent/utility/timer.rb +0 -26
  77. data/lib/concurrent_ruby.rb +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 470507742053628268cc6099862319dc532c8adf
4
- data.tar.gz: 744b0057156c93efd399e7c85de3adfd20be090c
3
+ metadata.gz: 73752ee1b21c6a7bed99d034af965e1f7bc12af7
4
+ data.tar.gz: 1d1cfe49be663c6bef102761aae9dfa6e29e26e8
5
5
  SHA512:
6
- metadata.gz: 86cb284c46ab9541832c4ba66dd57996750bb05af382a65a718569e46206204862d77c09c79ed9ba61823d0bc847af98c7766da81a4363034c84c0e4644e2712
7
- data.tar.gz: eb9a12909e6726ba9ede889066b81fe6bbe2e787e8e12f124300d11b5343b577ddcb7469087fada3abb7c481ce71b63a6a6144355775ac2329c410dd49ceef00
6
+ metadata.gz: 0246cc3adb6b535e7d3149663e5ef771575b0c75d92509e8517853d13c1c06133b354573e5c900308bef5cab7f141dd06d0a89f79493841e6d1b19f6110088a3
7
+ data.tar.gz: b5e8453b5123206bdaed3cc8122eb65077638a33b977f2d103be998ae42180cfe5bc23fc8eb921a9aab17208f4a26b4826211dd7e76b6275ba82ea705a49aec9
@@ -1,4 +1,18 @@
1
- ## Current Release v0.9.1 (09 August 2015)
1
+ ## Current Release v1.0.0.pre1 (19 Aug 2015)
2
+
3
+ * Merged in the `thread_safe` gem
4
+ - `Concurrent::Array`
5
+ - `Concurrent::Hash`
6
+ - `Concurrent::Map` (formerly ThreadSafe::Cache)
7
+ - `Concurrent::Tuple`
8
+ * Minor improvements to Concurrent::Map
9
+ * Complete rewrite of `Exchanger`
10
+ * Removed all deprecated code (classes, methods, constants, etc.)
11
+ * Updated Agent, MutexAtomic, and BufferedChannel to inherit from Synchronization::Object.
12
+ * Many improved tests
13
+ * Some internal reorganization
14
+
15
+ ### Release v0.9.1 (09 August 2015)
2
16
 
3
17
  * Fixed a Rubiniux bug in synchronization object
4
18
  * Fixed all interpreter warnings (except circular references)
data/README.md CHANGED
@@ -47,7 +47,7 @@
47
47
 
48
48
  MRI 1.9.3, 2.0, 2.1, 2.2, JRuby (1.9 mode), and Rubinius 2.x are supported.
49
49
  This gem should be fully compatible with any interpreter that is compliant with Ruby 1.9.3 or newer.
50
- Java 8 is required for JRuby (Java 7 support is deprecated in version 0.9 and will be removed in 1.0).
50
+ Java 8 is preferred for JRuby but every Java version on which JRuby 9000 runs will be supported.
51
51
 
52
52
  ## Features & Documentation
53
53
 
@@ -62,54 +62,62 @@ This library contains a variety of concurrency abstractions at high and low leve
62
62
  #### General-purpose Concurrency Abstractions
63
63
 
64
64
  * [Async](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Async.html): A mixin module that provides simple asynchronous behavior to any standard class/object or object.
65
- * [Atom](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Atom.html): A way to manage shared, synchronous, independent state.
66
65
  * [Future](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Future.html): An asynchronous operation that produces a value.
67
66
  * [Dataflow](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent.html#dataflow-class_method): Built on Futures, Dataflow allows you to create a task that will be scheduled when all of its data dependencies are available.
68
67
  * [Promise](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Promise.html): Similar to Futures, with more features.
69
68
  * [ScheduledTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ScheduledTask.html): Like a Future scheduled for a specific future time.
70
69
  * [TimerTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TimerTask.html): A Thread that periodically wakes up to perform work at regular intervals.
71
70
 
72
- #### Thread-safe Value Objects
71
+ #### Thread-safe Value Objects, Structures, and Collections
72
+
73
+ Collection classes that were originally part of the (deprecated) `thread_safe` gem:
74
+
75
+ * [Array](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Array.html) A thread-safe subclass of Ruby's standard [Array](http://ruby-doc.org/core-2.2.0/Array.html).
76
+ * [Hash](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Hash.html) A thread-safe subclass of Ruby's standard [Hash](http://ruby-doc.org/core-2.2.0/Hash.html).
77
+ * [Map](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Map.html) A hash-like object that should have much better performance characteristics, especially under high concurrency, than `Concurrent::Hash`.
78
+ * [Tuple](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Tuple.html) A fixed size array with volatile (synchronized, thread safe) getters/setters.
79
+
80
+ Value objects inspired by other languages:
73
81
 
74
- * `Maybe` A thread-safe, immutable object representing an optional value, based on
82
+ * [Atom](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Atom.html): A way to manage shared, synchronous, independent state.
83
+ * [Maybe](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Maybe.html) A thread-safe, immutable object representing an optional value, based on
75
84
  [Haskell Data.Maybe](https://hackage.haskell.org/package/base-4.2.0.1/docs/Data-Maybe.html).
76
- * `Delay` Lazy evaluation of a block yielding an immutable result. Based on Clojure's
85
+ * [Delay](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Delay.html) Lazy evaluation of a block yielding an immutable result. Based on Clojure's
77
86
  [delay](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Delay.html).
78
87
 
79
- #### Thread-safe Structures
88
+ Structure classes derived from Ruby's [Struct](http://ruby-doc.org/core-2.2.0/Struct.html):
89
+
90
+ * [ImmutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ImmutableStruct.html) Immutable struct where values are set at construction and cannot be changed later.
91
+ * [MutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MutableStruct.html) Synchronized, mutable struct where values can be safely changed at any time.
92
+ * [SettableStruct](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/SettableStruct.html) Synchronized, write-once struct where values can be set at most once, either at construction or any time thereafter.
80
93
 
81
- Derived from Ruby's [Struct](http://ruby-doc.org/core-2.2.0/Struct.html):
94
+ Thread-safe variables:
82
95
 
83
- * `ImmutableStruct` Immutable struct where values are set at construction and cannot be changed later.
84
- * `MutableStruct` Synchronized, mutable struct where values can be safely changed at any time.
85
- * `SettableStruct` Synchronized, write-once struct where values can be set at most once, either at construction or any time thereafter.
96
+ * [AtomicBoolean](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/AtomicBoolean.html) A boolean value that can be updated atomically.
97
+ * [AtomicFixnum](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/AtomicFixnum.html) A numeric value that can be updated atomically.
98
+ * [AtomicReference](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MutexAtomic.html) An object reference that may be updated atomically.
99
+ * [ThreadLocalVar](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ThreadLocalVar.html) A variable where the value is different for each thread.
86
100
 
87
101
  #### Java-inspired ThreadPools and Other Executors
88
102
 
89
- * See [ThreadPool](http://ruby-concurrency.github.io/concurrent-ruby/file.thread_pools.html) overview, which also contains a list of other Executors available.
103
+ * See the [thread pool](http://ruby-concurrency.github.io/concurrent-ruby/file.thread_pools.html) overview, which also contains a list of other Executors available.
90
104
 
91
105
  #### Thread Synchronization Classes and Algorithms
92
106
 
93
- * [CountdownLatch](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CountDownLatch.html)
94
- * [CyclicBarrier](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CyclicBarrier.html)
95
- * [Event](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Event.html)
96
- * [Semaphore](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Semaphore.html)
97
-
98
- #### Thread-safe Variables
99
-
100
- * [AtomicBoolean](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/AtomicBoolean.html)
101
- * [AtomicFixnum](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/AtomicFixnum.html)
102
- * [AtomicReference](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MutexAtomic.html)
103
- * [I-Structures](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/IVar.html) (IVar)
104
- * [M-Structures](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MVar.html) (MVar)
105
- * [Thread-local variables](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ThreadLocalVar.html)
106
- * [Software transactional memory](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TVar.html) (TVar)
107
- * [ReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ReadWriteLock.html)
108
- * [ReentrantReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ReentrantReadWriteLock.html)
107
+ * [CountdownLatch](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CountDownLatch.html) A synchronization object that allows one thread to wait on multiple other threads.
108
+ * [CyclicBarrier](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CyclicBarrier.html) A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.
109
+ * [Event](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Event.html) Old school kernel-style event.
110
+ * [Exchanger](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Exchanger.html)
111
+ * [I-Structure](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/IVar.html) (IVar) Similar to a "future" but can be manually assigned once, after which it becomes immutable.
112
+ * [M-Structure](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MVar.html) (MVar) A synchronized single element container.
113
+ * [ReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ReadWriteLock.html) A lock that supports multiple readers but only one writer.
114
+ * [ReentrantReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ReentrantReadWriteLock.html) A read/write lock with reentrant and upgrade features.
115
+ * [Semaphore](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Semaphore.html) A counting-based locking mechanism that uses permits.
116
+ * [Software transactional memory](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TVar.html) (TVar) A transactional variable - a single-element container that is used as part of a transaction.
109
117
 
110
118
  ### Edge Features
111
119
 
112
- These are available in the `concurrent-ruby-edge` companion gem, installed with `gem install concurrent-ruby-edge`.
120
+ These are available in the `concurrent-ruby-edge` companion gem.
113
121
 
114
122
  These features are under active development and may change frequently. They are expected not to
115
123
  keep backward compatibility (there may also lack tests and documentation). Semantic versions will
@@ -125,10 +133,9 @@ be obeyed though. Features developed in `concurrent-ruby-edge` are expected to m
125
133
  * [Agent](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Agent.html): A single atomic value that represents an identity.
126
134
  * [Channel](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Channel.html):
127
135
  Communicating Sequential Processes (CSP).
128
- * [Exchanger](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Exchanger.html)
129
136
  * [LazyRegister](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/LazyRegister.html)
130
- * [Atomic Markable Reference](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/AtomicMarkableReference.html)
131
- * [LockFreeLinked Set](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/LockFreeLinkedSet.html)
137
+ * [AtomicMarkableReference](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/AtomicMarkableReference.html)
138
+ * [LockFreeLinkedSet](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/LockFreeLinkedSet.html)
132
139
  * [LockFreeStack](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/LockFreeStack.html)
133
140
 
134
141
  #### Statuses:
@@ -139,52 +146,21 @@ be obeyed though. Features developed in `concurrent-ruby-edge` are expected to m
139
146
  - **Future/Promise Framework** - API changes; partial documentation and tests; stability good.
140
147
  - **Agent** - Incomplete behaviour compared to Clojure's models; stability good.
141
148
  - **Channel** - Missing documentation; limted features; stability good.
142
- - **Exchanger** - Known race condition requiring a new implementation.
143
149
  - **LazyRegister** - Missing documentation and tests.
144
150
  - **AtomicMarkableReference, LockFreeLinkedSet, LockFreeStack** - Needs real world battle testing
145
151
 
146
152
  ## Usage
147
153
 
148
- All abstractions within this gem can be loaded simply by requiring it:
154
+ Everything within this gem can be loaded simply by requiring it:
149
155
 
150
156
  ```ruby
151
157
  require 'concurrent'
152
158
  ```
153
159
 
154
- To reduce the amount of code loaded at runtime, subsets of this gem can be required:
160
+ To use the tools in the Edge gem it must be required separately:
155
161
 
156
162
  ```ruby
157
- require 'concurrent' # everything
158
-
159
- # groups
160
-
161
- require 'concurrent/atomics' # atomic and thread synchronization classes
162
- require 'concurrent/executors' # Thread pools and other executors
163
-
164
- # individual abstractions
165
-
166
- require 'concurrent/async' # Concurrent::Async
167
- require 'concurrent/atom' # Concurrent::Atom
168
- require 'concurrent/dataflow' # Concurrent::dataflow
169
- require 'concurrent/delay' # Concurrent::Delay
170
- require 'concurrent/future' # Concurrent::Future
171
- require 'concurrent/immutable_struct' # Concurrent::ImmutableStruct
172
- require 'concurrent/ivar' # Concurrent::IVar
173
- require 'concurrent/maybe' # Concurrent::Maybe
174
- require 'concurrent/mutable_struct' # Concurrent::MutableStruct
175
- require 'concurrent/mvar' # Concurrent::MVar
176
- require 'concurrent/promise' # Concurrent::Promise
177
- require 'concurrent/scheduled_task' # Concurrent::ScheduledTask
178
- require 'concurrent/settable_struct' # Concurrent::SettableStruct
179
- require 'concurrent/timer_task' # Concurrent::TimerTask
180
- require 'concurrent/tvar' # Concurrent::TVar
181
-
182
- # experimental - available in `concurrent-ruby-edge` companion gem
183
-
184
- require 'concurrent/actor' # Concurrent::Actor and supporting code
185
- require 'concurrent/edge/future' # new Future Framework
186
- require 'concurrent/agent' # Concurrent::Agent
187
- require 'concurrent/channel ' # Concurrent::Channel and supporting code
163
+ require 'concurrent-edge'
188
164
  ```
189
165
 
190
166
  If the library does not behave as expected, `Concurrent.use_stdlib_logger(Logger::DEBUG)` could help to reveal the problem.
@@ -203,6 +179,23 @@ gem 'concurrent-ruby'
203
179
 
204
180
  and run `bundle install` from your shell.
205
181
 
182
+ ### Edge Gem Installation
183
+
184
+ The Edge gem must be installed separately from the core gem:
185
+
186
+ ```shell
187
+ gem install concurrent-ruby-edge
188
+ ```
189
+
190
+ or add the following line to Gemfile:
191
+
192
+ ```ruby
193
+ gem 'concurrent-ruby-edge'
194
+ ```
195
+
196
+ and run `bundle install` from your shell.
197
+
198
+
206
199
  ### C Extensions for MRI
207
200
 
208
201
  Potential performance improvements may be achieved under MRI by installing optional C extensions.
@@ -240,7 +233,7 @@ The best practice is to depend on `concurrent-ruby` and let users to decide if t
240
233
 
241
234
  All published versions of this gem (core, extension, and several platform-specific packages) are compiled,
242
235
  packaged, tested, and published using an open, [automated process](https://github.com/ruby-concurrency/rake-compiler-dev-box).
243
- This process can also be used to create pre-compiled binaries of the extension gem for virtally
236
+ This process can also be used to create pre-compiled binaries of the extension gem for virtually
244
237
  any platform. *Documentation is forthcoming...*
245
238
 
246
239
  ```
@@ -272,11 +265,17 @@ bundle exec rake compile # Compile all the extensions
272
265
  ## Maintainers
273
266
 
274
267
  * [Jerry D'Antonio](https://github.com/jdantonio) (creator)
268
+ * [Petr Chalupa](https://github.com/pitr-ch)
275
269
  * [Michele Della Torre](https://github.com/mighe)
276
270
  * [Chris Seaton](https://github.com/chrisseaton)
277
- * [Lucas Allan](https://github.com/lucasallan)
278
- * [Petr Chalupa](https://github.com/pitr-ch)
279
271
  * [Paweł Obrok](https://github.com/obrok)
272
+ * [Lucas Allan](https://github.com/lucasallan)
273
+
274
+ ### Special Thanks
275
+
276
+ * [Brian Durand](https://github.com/bdurand) for the `ref` gem
277
+ * [Charles Oliver Nutter](https://github.com/headius) for the `atomic` and `thread_safe` gems
278
+ * [thedarkone](https://github.com/thedarkone) for the `thread_safe` gem
280
279
 
281
280
  ## Contributing
282
281
 
@@ -7,13 +7,17 @@ require 'concurrent/configuration'
7
7
  require 'concurrent/atomics'
8
8
  require 'concurrent/errors'
9
9
  require 'concurrent/executors'
10
- require 'concurrent/utilities'
11
10
 
12
11
  require 'concurrent/atomic/atomic_reference'
13
12
  require 'concurrent/atom'
13
+ require 'concurrent/array'
14
+ require 'concurrent/hash'
15
+ require 'concurrent/map'
16
+ require 'concurrent/tuple'
14
17
  require 'concurrent/async'
15
18
  require 'concurrent/dataflow'
16
19
  require 'concurrent/delay'
20
+ require 'concurrent/exchanger'
17
21
  require 'concurrent/future'
18
22
  require 'concurrent/immutable_struct'
19
23
  require 'concurrent/ivar'
@@ -26,6 +30,10 @@ require 'concurrent/settable_struct'
26
30
  require 'concurrent/timer_task'
27
31
  require 'concurrent/tvar'
28
32
 
33
+ require 'concurrent/thread_safe/synchronized_delegator'
34
+ require 'concurrent/thread_safe/util'
35
+
36
+
29
37
  # @!macro [new] internal_implementation_note
30
38
  #
31
39
  # @note **Private Implementation:** This abstraction is a private, internal
@@ -118,4 +126,9 @@ require 'concurrent/tvar'
118
126
  # * Be small, lean, and loosely coupled
119
127
  module Concurrent
120
128
 
129
+ # Various classes within allows for +nil+ values to be stored,
130
+ # so a special +NULL+ token is required to indicate the "nil-ness".
131
+ # @!visibility private
132
+ NULL = Object.new
133
+
121
134
  end
@@ -0,0 +1,38 @@
1
+ require 'concurrent/utility/engine'
2
+ require 'concurrent/thread_safe/util'
3
+
4
+ module Concurrent
5
+ if Concurrent.on_cruby?
6
+
7
+ # Because MRI never runs code in parallel, the existing
8
+ # non-thread-safe structures should usually work fine.
9
+
10
+ # @!macro [attach] concurrent_array
11
+ #
12
+ # A thread-safe subclass of Array. This version locks against the object
13
+ # itself for every method call, ensuring only one thread can be reading
14
+ # or writing at a time. This includes iteration methods like `#each`.
15
+ #
16
+ # @see http://ruby-doc.org/core-2.2.0/Array.html Ruby standard library `Array`
17
+ class Array < ::Array;
18
+ end
19
+
20
+ elsif Concurrent.on_jruby?
21
+ require 'jruby/synchronized'
22
+
23
+ # @!macro concurrent_array
24
+ class Array < ::Array
25
+ include JRuby::Synchronized
26
+ end
27
+
28
+ elsif Concurrent.on_rbx?
29
+ require 'monitor'
30
+
31
+ # @!macro concurrent_array
32
+ class Array < ::Array
33
+ end
34
+
35
+ ThreadSafe::Util.make_synchronized_on_rbx Array
36
+ end
37
+ end
38
+
@@ -5,7 +5,6 @@ require 'concurrent/errors'
5
5
  require 'concurrent/ivar'
6
6
  require 'concurrent/executor/immediate_executor'
7
7
  require 'concurrent/executor/serialized_execution'
8
- require 'concurrent/concern/deprecation'
9
8
 
10
9
  module Concurrent
11
10
 
@@ -248,22 +247,6 @@ module Concurrent
248
247
  raise ArgumentError.new('executor has already been set')
249
248
  end
250
249
 
251
- # Initialize the internal serializer and other stnchronization mechanisms.
252
- #
253
- # @note This method *must* be called immediately upon object construction.
254
- # This is the only way thread-safe initialization can be guaranteed.
255
- #
256
- # @raise [Concurrent::InitializationError] when called more than once
257
- #
258
- # @!visibility private
259
- # @deprecated
260
- def init_mutex
261
- deprecated 'mutex synchronization now happens automatically'
262
- init_synchronization
263
- rescue InitializationError
264
- # suppress
265
- end
266
-
267
250
  private
268
251
 
269
252
  # Initialize the internal serializer and other stnchronization mechanisms.
@@ -0,0 +1,40 @@
1
+ module Concurrent
2
+
3
+ # @!macro thread_local_var
4
+ # @!macro internal_implementation_note
5
+ # @!visibility private
6
+ class AbstractThreadLocalVar
7
+
8
+ # @!visibility private
9
+ NIL_SENTINEL = Object.new
10
+ private_constant :NIL_SENTINEL
11
+
12
+ # @!macro thread_local_var_method_initialize
13
+ def initialize(default = nil)
14
+ @default = default
15
+ allocate_storage
16
+ end
17
+
18
+ # @!macro thread_local_var_method_get
19
+ def value
20
+ raise NotImplementedError
21
+ end
22
+
23
+ # @!macro thread_local_var_method_set
24
+ def value=(value)
25
+ raise NotImplementedError
26
+ end
27
+
28
+ # @!macro thread_local_var_method_bind
29
+ def bind(value, &block)
30
+ raise NotImplementedError
31
+ end
32
+
33
+ protected
34
+
35
+ # @!visibility private
36
+ def allocate_storage
37
+ raise NotImplementedError
38
+ end
39
+ end
40
+ end
@@ -1,113 +1,80 @@
1
+ require 'concurrent/atomic/mutex_atomic_boolean'
1
2
  require 'concurrent/utility/native_extension_loader'
2
- require 'concurrent/synchronization'
3
3
 
4
4
  module Concurrent
5
5
 
6
- # @!macro [attach] atomic_boolean
6
+ ###################################################################
7
+
8
+ # @!macro [new] atomic_boolean_method_initialize
7
9
  #
8
- # A boolean value that can be updated atomically. Reads and writes to an atomic
9
- # boolean and thread-safe and guaranteed to succeed. Reads and writes may block
10
- # briefly but no explicit locking is required.
10
+ # Creates a new `AtomicBoolean` with the given initial value.
11
11
  #
12
- # Testing with ruby 2.1.2
13
- # Testing with Concurrent::MutexAtomicBoolean...
14
- # 2.790000 0.000000 2.790000 ( 2.791454)
15
- # Testing with Concurrent::CAtomicBoolean...
16
- # 0.740000 0.000000 0.740000 ( 0.740206)
12
+ # @param [Boolean] initial the initial value
13
+
14
+ # @!macro [new] atomic_boolean_method_value_get
17
15
  #
18
- # Testing with jruby 1.9.3
19
- # Testing with Concurrent::MutexAtomicBoolean...
20
- # 5.240000 2.520000 7.760000 ( 3.683000)
21
- # Testing with Concurrent::JavaAtomicBoolean...
22
- # 3.340000 0.010000 3.350000 ( 0.855000)
16
+ # Retrieves the current `Boolean` value.
23
17
  #
24
- # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html java.util.concurrent.atomic.AtomicBoolean
18
+ # @return [Boolean] the current value
19
+
20
+ # @!macro [new] atomic_boolean_method_value_set
25
21
  #
26
- # @!visibility private
22
+ # Explicitly sets the value.
27
23
  #
28
- # @!macro internal_implementation_note
29
- class MutexAtomicBoolean < Synchronization::Object
30
-
31
- # @!macro [attach] atomic_boolean_method_initialize
32
- #
33
- # Creates a new `AtomicBoolean` with the given initial value.
34
- #
35
- # @param [Boolean] initial the initial value
36
- def initialize(initial = false)
37
- super()
38
- synchronize { ns_initialize(initial) }
39
- end
40
-
41
- # @!macro [attach] atomic_boolean_method_value_get
42
- #
43
- # Retrieves the current `Boolean` value.
44
- #
45
- # @return [Boolean] the current value
46
- def value
47
- synchronize { @value }
48
- end
49
-
50
- # @!macro [attach] atomic_boolean_method_value_set
51
- #
52
- # Explicitly sets the value.
53
- #
54
- # @param [Boolean] value the new value to be set
55
- #
56
- # @return [Boolean] the current value
57
- def value=(value)
58
- synchronize { @value = !!value }
59
- end
60
-
61
- # @!macro [attach] atomic_boolean_method_true_question
62
- #
63
- # Is the current value `true`
64
- #
65
- # @return [Boolean] true if the current value is `true`, else false
66
- def true?
67
- synchronize { @value }
68
- end
24
+ # @param [Boolean] value the new value to be set
25
+ #
26
+ # @return [Boolean] the current value
69
27
 
70
- # @!macro [attach] atomic_boolean_method_false_question
71
- #
72
- # Is the current value `false`
73
- #
74
- # @return [Boolean] true if the current value is `false`, else false
75
- def false?
76
- synchronize { !@value }
77
- end
28
+ # @!macro [new] atomic_boolean_method_true_question
29
+ #
30
+ # Is the current value `true`
31
+ #
32
+ # @return [Boolean] true if the current value is `true`, else false
78
33
 
79
- # @!macro [attach] atomic_boolean_method_make_true
80
- #
81
- # Explicitly sets the value to true.
82
- #
83
- # @return [Boolean] true is value has changed, otherwise false
84
- def make_true
85
- synchronize { ns_make_value(true) }
86
- end
34
+ # @!macro [new] atomic_boolean_method_false_question
35
+ #
36
+ # Is the current value `false`
37
+ #
38
+ # @return [Boolean] true if the current value is `false`, else false
87
39
 
88
- # @!macro [attach] atomic_boolean_method_make_false
89
- #
90
- # Explicitly sets the value to false.
91
- #
92
- # @return [Boolean] true is value has changed, otherwise false
93
- def make_false
94
- synchronize { ns_make_value(false) }
95
- end
40
+ # @!macro [new] atomic_boolean_method_make_true
41
+ #
42
+ # Explicitly sets the value to true.
43
+ #
44
+ # @return [Boolean] true is value has changed, otherwise false
96
45
 
97
- protected
46
+ # @!macro [new] atomic_boolean_method_make_false
47
+ #
48
+ # Explicitly sets the value to false.
49
+ #
50
+ # @return [Boolean] true is value has changed, otherwise false
51
+
52
+ ###################################################################
98
53
 
99
- # @!visibility private
100
- def ns_initialize(initial)
101
- @value = !!initial
102
- end
54
+ # @!macro [new] atomic_boolean_public_api
55
+ #
56
+ # @!method initialize(initial = false)
57
+ # @!macro atomic_boolean_method_initialize
58
+ #
59
+ # @!method value
60
+ # @!macro atomic_boolean_method_value_get
61
+ #
62
+ # @!method value=(value)
63
+ # @!macro atomic_boolean_method_value_set
64
+ #
65
+ # @!method true?
66
+ # @!macro atomic_boolean_method_true_question
67
+ #
68
+ # @!method false?
69
+ # @!macro atomic_boolean_method_false_question
70
+ #
71
+ # @!method make_true
72
+ # @!macro atomic_boolean_method_make_true
73
+ #
74
+ # @!method make_false
75
+ # @!macro atomic_boolean_method_make_false
103
76
 
104
- # @!visibility private
105
- def ns_make_value(value)
106
- old = @value
107
- @value = value
108
- old != @value
109
- end
110
- end
77
+ ###################################################################
111
78
 
112
79
  # @!visibility private
113
80
  # @!macro internal_implementation_note
@@ -121,31 +88,27 @@ module Concurrent
121
88
  end
122
89
  private_constant :AtomicBooleanImplementation
123
90
 
124
- # @!macro atomic_boolean
91
+ # @!macro [attach] atomic_boolean
92
+ #
93
+ # A boolean value that can be updated atomically. Reads and writes to an atomic
94
+ # boolean and thread-safe and guaranteed to succeed. Reads and writes may block
95
+ # briefly but no explicit locking is required.
96
+ #
97
+ # Testing with ruby 2.1.2
98
+ # Testing with Concurrent::MutexAtomicBoolean...
99
+ # 2.790000 0.000000 2.790000 ( 2.791454)
100
+ # Testing with Concurrent::CAtomicBoolean...
101
+ # 0.740000 0.000000 0.740000 ( 0.740206)
102
+ #
103
+ # Testing with jruby 1.9.3
104
+ # Testing with Concurrent::MutexAtomicBoolean...
105
+ # 5.240000 2.520000 7.760000 ( 3.683000)
106
+ # Testing with Concurrent::JavaAtomicBoolean...
107
+ # 3.340000 0.010000 3.350000 ( 0.855000)
108
+ #
109
+ # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html java.util.concurrent.atomic.AtomicBoolean
125
110
  #
126
- # @see Concurrent::MutexAtomicBoolean
111
+ # @!macro atomic_boolean_public_api
127
112
  class AtomicBoolean < AtomicBooleanImplementation
128
-
129
- # @!method initialize(initial = false)
130
- # @!macro atomic_boolean_method_initialize
131
-
132
- # @!method value
133
- # @!macro atomic_boolean_method_value_get
134
-
135
- # @!method value=(value)
136
- # @!macro atomic_boolean_method_value_set
137
-
138
- # @!method true?
139
- # @!macro atomic_boolean_method_true_question
140
-
141
- # @!method false?
142
- # @!macro atomic_boolean_method_false_question
143
-
144
- # @!method make_true
145
- # @!macro atomic_boolean_method_make_true
146
-
147
- # @!method make_false
148
- # @!macro atomic_boolean_method_make_false
149
-
150
113
  end
151
114
  end