concurrent-ruby 1.0.0.pre1-java → 1.0.0.pre2-java
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -1
- data/README.md +16 -18
- data/lib/concurrent.rb +3 -3
- data/lib/concurrent/agent.rb +583 -0
- data/lib/concurrent/array.rb +1 -0
- data/lib/concurrent/async.rb +236 -111
- data/lib/concurrent/atom.rb +101 -46
- data/lib/concurrent/atomic/atomic_boolean.rb +2 -0
- data/lib/concurrent/atomic/atomic_fixnum.rb +2 -0
- data/lib/concurrent/atomic/cyclic_barrier.rb +1 -1
- data/lib/concurrent/atomic/event.rb +1 -1
- data/lib/concurrent/atomic/mutex_atomic_boolean.rb +1 -1
- data/lib/concurrent/atomic/mutex_atomic_fixnum.rb +1 -1
- data/lib/concurrent/atomic/mutex_count_down_latch.rb +1 -1
- data/lib/concurrent/atomic/mutex_semaphore.rb +2 -2
- data/lib/concurrent/atomic/read_write_lock.rb +5 -4
- data/lib/concurrent/atomic/reentrant_read_write_lock.rb +3 -1
- data/lib/concurrent/atomic/thread_local_var.rb +2 -0
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +1 -1
- data/lib/concurrent/atomics.rb +6 -4
- data/lib/concurrent/collection/copy_on_notify_observer_set.rb +7 -15
- data/lib/concurrent/collection/copy_on_write_observer_set.rb +7 -15
- data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +5 -0
- data/lib/concurrent/concern/observable.rb +38 -13
- data/lib/concurrent/configuration.rb +5 -4
- data/lib/concurrent/delay.rb +9 -8
- data/lib/concurrent/exchanger.rb +2 -0
- data/lib/concurrent/executor/abstract_executor_service.rb +2 -2
- data/lib/concurrent/executor/java_single_thread_executor.rb +0 -1
- data/lib/concurrent/executor/ruby_executor_service.rb +10 -4
- data/lib/concurrent/executor/ruby_single_thread_executor.rb +10 -68
- data/lib/concurrent/executor/safe_task_executor.rb +7 -8
- data/lib/concurrent/executor/serialized_execution.rb +4 -4
- data/lib/concurrent/executor/single_thread_executor.rb +20 -10
- data/lib/concurrent/executor/timer_set.rb +4 -2
- data/lib/concurrent/executors.rb +0 -1
- data/lib/concurrent/future.rb +3 -2
- data/lib/concurrent/hash.rb +1 -1
- data/lib/concurrent/immutable_struct.rb +5 -1
- data/lib/concurrent/ivar.rb +1 -1
- data/lib/concurrent/mutable_struct.rb +7 -6
- data/lib/concurrent/{executor/executor.rb → options.rb} +4 -3
- data/lib/concurrent/promise.rb +3 -2
- data/lib/concurrent/scheduled_task.rb +3 -2
- data/lib/concurrent/settable_struct.rb +5 -4
- data/lib/concurrent/synchronization.rb +11 -3
- data/lib/concurrent/synchronization/abstract_lockable_object.rb +117 -0
- data/lib/concurrent/synchronization/abstract_object.rb +16 -129
- data/lib/concurrent/synchronization/abstract_struct.rb +2 -3
- data/lib/concurrent/synchronization/condition.rb +6 -4
- data/lib/concurrent/synchronization/jruby_lockable_object.rb +13 -0
- data/lib/concurrent/synchronization/{java_object.rb → jruby_object.rb} +5 -3
- data/lib/concurrent/synchronization/lock.rb +3 -2
- data/lib/concurrent/synchronization/lockable_object.rb +59 -0
- data/lib/concurrent/synchronization/mri_lockable_object.rb +71 -0
- data/lib/concurrent/synchronization/mri_object.rb +35 -0
- data/lib/concurrent/synchronization/object.rb +111 -39
- data/lib/concurrent/synchronization/rbx_lockable_object.rb +64 -0
- data/lib/concurrent/synchronization/rbx_object.rb +17 -68
- data/lib/concurrent/thread_safe/util.rb +0 -9
- data/lib/concurrent/thread_safe/util/adder.rb +3 -0
- data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +3 -1
- data/lib/concurrent/thread_safe/util/cheap_lockable.rb +3 -0
- data/lib/concurrent/thread_safe/util/power_of_two_tuple.rb +1 -0
- data/lib/concurrent/thread_safe/util/striped64.rb +6 -1
- data/lib/concurrent/thread_safe/util/volatile.rb +2 -0
- data/lib/concurrent/thread_safe/util/xor_shift_random.rb +2 -0
- data/lib/concurrent/tvar.rb +36 -0
- data/lib/concurrent/utility/at_exit.rb +1 -1
- data/lib/concurrent/utility/monotonic_time.rb +3 -4
- data/lib/concurrent/utility/native_extension_loader.rb +1 -1
- data/lib/concurrent/version.rb +2 -2
- data/lib/concurrent_ruby_ext.jar +0 -0
- metadata +11 -6
- data/lib/concurrent/synchronization/monitor_object.rb +0 -27
- data/lib/concurrent/synchronization/mutex_object.rb +0 -43
@@ -0,0 +1,64 @@
|
|
1
|
+
module Concurrent
|
2
|
+
module Synchronization
|
3
|
+
|
4
|
+
# @!visibility private
|
5
|
+
# @!macro internal_implementation_note
|
6
|
+
class RbxLockableObject < AbstractLockableObject
|
7
|
+
safe_initialization!
|
8
|
+
|
9
|
+
def initialize(*defaults)
|
10
|
+
super(*defaults)
|
11
|
+
@__Waiters__ = []
|
12
|
+
@__owner__ = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def synchronize(&block)
|
18
|
+
if @__owner__ == Thread.current
|
19
|
+
yield
|
20
|
+
else
|
21
|
+
Rubinius.lock(self)
|
22
|
+
begin
|
23
|
+
@__owner__ = Thread.current
|
24
|
+
result = yield
|
25
|
+
ensure
|
26
|
+
@__owner__ = nil
|
27
|
+
Rubinius.unlock(self)
|
28
|
+
result
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def ns_wait(timeout = nil)
|
34
|
+
wchan = Rubinius::Channel.new
|
35
|
+
|
36
|
+
begin
|
37
|
+
@__Waiters__.push wchan
|
38
|
+
Rubinius.unlock(self)
|
39
|
+
signaled = wchan.receive_timeout timeout
|
40
|
+
ensure
|
41
|
+
Rubinius.lock(self)
|
42
|
+
|
43
|
+
if !signaled && !@__Waiters__.delete(wchan)
|
44
|
+
# we timed out, but got signaled afterwards,
|
45
|
+
# so pass that signal on to the next waiter
|
46
|
+
@__Waiters__.shift << true unless @__Waiters__.empty?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def ns_signal
|
54
|
+
@__Waiters__.shift << true unless @__Waiters__.empty?
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
def ns_broadcast
|
59
|
+
@__Waiters__.shift << true until @__Waiters__.empty?
|
60
|
+
self
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -1,74 +1,23 @@
|
|
1
1
|
module Concurrent
|
2
2
|
module Synchronization
|
3
3
|
|
4
|
-
if Concurrent.on_rbx?
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
ensure_ivar_visibility!
|
13
|
-
end
|
14
|
-
|
15
|
-
protected
|
16
|
-
|
17
|
-
def synchronize(&block)
|
18
|
-
if @__owner__ == Thread.current
|
19
|
-
yield
|
20
|
-
else
|
21
|
-
Rubinius.lock(self)
|
22
|
-
begin
|
23
|
-
@__owner__ = Thread.current
|
24
|
-
result = yield
|
25
|
-
ensure
|
26
|
-
@__owner__ = nil
|
27
|
-
Rubinius.unlock(self)
|
28
|
-
result
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def ns_wait(timeout = nil)
|
34
|
-
wchan = Rubinius::Channel.new
|
35
|
-
|
36
|
-
begin
|
37
|
-
@__Waiters__.push wchan
|
38
|
-
Rubinius.unlock(self)
|
39
|
-
signaled = wchan.receive_timeout timeout
|
40
|
-
ensure
|
41
|
-
Rubinius.lock(self)
|
42
|
-
|
43
|
-
if !signaled && !@__Waiters__.delete(wchan)
|
44
|
-
# we timed out, but got signaled afterwards,
|
45
|
-
# so pass that signal on to the next waiter
|
46
|
-
@__Waiters__.shift << true unless @__Waiters__.empty?
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
self
|
51
|
-
end
|
52
|
-
|
53
|
-
def ns_signal
|
54
|
-
@__Waiters__.shift << true unless @__Waiters__.empty?
|
55
|
-
self
|
56
|
-
end
|
57
|
-
|
58
|
-
def ns_broadcast
|
59
|
-
@__Waiters__.shift << true until @__Waiters__.empty?
|
60
|
-
self
|
61
|
-
end
|
5
|
+
# @!visibility private
|
6
|
+
# @!macro internal_implementation_note
|
7
|
+
class RbxObject < AbstractObject
|
8
|
+
def initialize
|
9
|
+
# nothing to do
|
10
|
+
end
|
62
11
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
12
|
+
def full_memory_barrier
|
13
|
+
# Rubinius instance variables are not volatile so we need to insert barrier
|
14
|
+
Rubinius.memory_barrier
|
15
|
+
end
|
67
16
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
17
|
+
def self.attr_volatile *names
|
18
|
+
names.each do |name|
|
19
|
+
ivar = :"@volatile_#{name}"
|
20
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
72
21
|
def #{name}
|
73
22
|
Rubinius.memory_barrier
|
74
23
|
#{ivar}
|
@@ -78,11 +27,11 @@ module Concurrent
|
|
78
27
|
#{ivar} = value
|
79
28
|
Rubinius.memory_barrier
|
80
29
|
end
|
81
|
-
|
82
|
-
end
|
83
|
-
names.map { |n| [n, :"#{n}="] }.flatten
|
30
|
+
RUBY
|
84
31
|
end
|
32
|
+
names.map { |n| [n, :"#{n}="] }.flatten
|
85
33
|
end
|
86
34
|
end
|
35
|
+
|
87
36
|
end
|
88
37
|
end
|
@@ -12,12 +12,3 @@ module Concurrent
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
15
|
-
|
16
|
-
require 'concurrent/tuple'
|
17
|
-
require 'concurrent/thread_safe/util/xor_shift_random'
|
18
|
-
require 'concurrent/thread_safe/util/volatile'
|
19
|
-
require 'concurrent/thread_safe/util/striped64'
|
20
|
-
require 'concurrent/thread_safe/util/adder'
|
21
|
-
require 'concurrent/thread_safe/util/cheap_lockable'
|
22
|
-
require 'concurrent/thread_safe/util/power_of_two_tuple'
|
23
|
-
require 'concurrent/thread_safe/util/array_hash_rbx'
|
@@ -1,3 +1,8 @@
|
|
1
|
+
require 'concurrent/thread_safe/util'
|
2
|
+
require 'concurrent/thread_safe/util/power_of_two_tuple'
|
3
|
+
require 'concurrent/thread_safe/util/volatile'
|
4
|
+
require 'concurrent/thread_safe/util/xor_shift_random'
|
5
|
+
|
1
6
|
module Concurrent
|
2
7
|
|
3
8
|
# @!visibility private
|
@@ -83,7 +88,7 @@ module Concurrent
|
|
83
88
|
|
84
89
|
# TODO: this only adds padding after the :value slot, need to find a way to add padding before the slot
|
85
90
|
# @!visibility private
|
86
|
-
attr_reader *(
|
91
|
+
attr_reader *(12.times.collect{ |i| "padding_#{i}".to_sym })
|
87
92
|
|
88
93
|
alias_method :cas, :compare_and_set
|
89
94
|
|
data/lib/concurrent/tvar.rb
CHANGED
@@ -1,10 +1,46 @@
|
|
1
1
|
require 'set'
|
2
2
|
|
3
|
+
# @!macro [new] thread_safe_variable_comparison
|
4
|
+
#
|
5
|
+
# ## Thread-safe Variable Classes
|
6
|
+
#
|
7
|
+
# Each of the thread-safe variable classes is designed to solve a different
|
8
|
+
# problem. In general:
|
9
|
+
#
|
10
|
+
# * *{Concurrent::Agent}:* Shared, mutable variable providing independent,
|
11
|
+
# uncoordinated, *asynchronous* change of individual values. Best used when
|
12
|
+
# the value will undergo frequent, complex updates. Suitable when the result
|
13
|
+
# of an update does not need to be known immediately.
|
14
|
+
# * *{Concurrent::Atom}:* Shared, mutable variable providing independent,
|
15
|
+
# uncoordinated, *synchronous* change of individual values. Best used when
|
16
|
+
# the value will undergo frequent reads but only occasional, though complex,
|
17
|
+
# updates. Suitable when the result of an update must be known immediately.
|
18
|
+
# * *{Concurrent::AtomicReference}:* A simple object reference that can be
|
19
|
+
# atomically. Updates are synchronous but fast. Bast used when updates a
|
20
|
+
# simple set operations. Not suitable when updates are complex.
|
21
|
+
# {Concurrent::AtomicBoolean} and {Concurrent::AtomicFixnum} are similar
|
22
|
+
# but optimized for the given data type.
|
23
|
+
# * *{Concurrent::Exchanger}:* Shared, stateless synchronization point. Used
|
24
|
+
# when two or more threads need to exchange data. The threads will pair then
|
25
|
+
# block on each other until the exchange is complete.
|
26
|
+
# * *{Concurrent::MVar}:* Shared synchronization point. Used when one thread
|
27
|
+
# must give a value to another, which must take the value. The threads will
|
28
|
+
# block on each other until the exchange is complete.
|
29
|
+
# * *{Concurrent::ThreadLocalVar}:* Shared, mutable, isolated variable which
|
30
|
+
# holds a different value for each thread which has access. Often used as
|
31
|
+
# an instance variable in objects which must maintain different state
|
32
|
+
# for different threads.
|
33
|
+
# * *{Concurrent::TVar}:* Shared, mutable variables which provide
|
34
|
+
# *coordinated*, *synchronous*, change of *many* stated. Used when multiple
|
35
|
+
# value must change together, in an all-or-nothing transaction.
|
36
|
+
|
3
37
|
module Concurrent
|
4
38
|
|
5
39
|
# A `TVar` is a transactional variable - a single-element container that
|
6
40
|
# is used as part of a transaction - see `Concurrent::atomically`.
|
7
41
|
#
|
42
|
+
# @!macro thread_safe_variable_comparison
|
43
|
+
#
|
8
44
|
# {include:file:doc/tvar.md}
|
9
45
|
class TVar
|
10
46
|
|
@@ -7,7 +7,7 @@ module Concurrent
|
|
7
7
|
# Each handler is executed at most once.
|
8
8
|
#
|
9
9
|
# @!visibility private
|
10
|
-
class AtExitImplementation < Synchronization::
|
10
|
+
class AtExitImplementation < Synchronization::LockableObject
|
11
11
|
include Logger::Severity
|
12
12
|
|
13
13
|
def initialize(*args)
|
@@ -2,11 +2,10 @@ require 'concurrent/synchronization'
|
|
2
2
|
|
3
3
|
module Concurrent
|
4
4
|
|
5
|
-
class_definition = Class.new(Synchronization::
|
5
|
+
class_definition = Class.new(Synchronization::LockableObject) do
|
6
6
|
def initialize
|
7
|
-
super()
|
8
7
|
@last_time = Time.now.to_f
|
9
|
-
|
8
|
+
super()
|
10
9
|
end
|
11
10
|
|
12
11
|
if defined?(Process::CLOCK_MONOTONIC)
|
@@ -44,7 +43,7 @@ module Concurrent
|
|
44
43
|
private_constant :GLOBAL_MONOTONIC_CLOCK
|
45
44
|
|
46
45
|
# @!macro [attach] monotonic_get_time
|
47
|
-
#
|
46
|
+
#
|
48
47
|
# Returns the current time a tracked by the application monotonic clock.
|
49
48
|
#
|
50
49
|
# @return [Float] The current monotonic time when `since` not given else
|
data/lib/concurrent/version.rb
CHANGED
data/lib/concurrent_ruby_ext.jar
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: concurrent-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.pre2
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Jerry D'Antonio
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-09-19 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: |
|
15
15
|
Modern concurrency tools including agents, futures, promises, thread pools, actors, supervisors, and more.
|
@@ -28,6 +28,7 @@ files:
|
|
28
28
|
- LICENSE.txt
|
29
29
|
- README.md
|
30
30
|
- lib/concurrent.rb
|
31
|
+
- lib/concurrent/agent.rb
|
31
32
|
- lib/concurrent/array.rb
|
32
33
|
- lib/concurrent/async.rb
|
33
34
|
- lib/concurrent/atom.rb
|
@@ -79,7 +80,6 @@ files:
|
|
79
80
|
- lib/concurrent/exchanger.rb
|
80
81
|
- lib/concurrent/executor/abstract_executor_service.rb
|
81
82
|
- lib/concurrent/executor/cached_thread_pool.rb
|
82
|
-
- lib/concurrent/executor/executor.rb
|
83
83
|
- lib/concurrent/executor/executor_service.rb
|
84
84
|
- lib/concurrent/executor/fixed_thread_pool.rb
|
85
85
|
- lib/concurrent/executor/immediate_executor.rb
|
@@ -108,18 +108,23 @@ files:
|
|
108
108
|
- lib/concurrent/maybe.rb
|
109
109
|
- lib/concurrent/mutable_struct.rb
|
110
110
|
- lib/concurrent/mvar.rb
|
111
|
+
- lib/concurrent/options.rb
|
111
112
|
- lib/concurrent/promise.rb
|
112
113
|
- lib/concurrent/scheduled_task.rb
|
113
114
|
- lib/concurrent/settable_struct.rb
|
114
115
|
- lib/concurrent/synchronization.rb
|
116
|
+
- lib/concurrent/synchronization/abstract_lockable_object.rb
|
115
117
|
- lib/concurrent/synchronization/abstract_object.rb
|
116
118
|
- lib/concurrent/synchronization/abstract_struct.rb
|
117
119
|
- lib/concurrent/synchronization/condition.rb
|
118
|
-
- lib/concurrent/synchronization/
|
120
|
+
- lib/concurrent/synchronization/jruby_lockable_object.rb
|
121
|
+
- lib/concurrent/synchronization/jruby_object.rb
|
119
122
|
- lib/concurrent/synchronization/lock.rb
|
120
|
-
- lib/concurrent/synchronization/
|
121
|
-
- lib/concurrent/synchronization/
|
123
|
+
- lib/concurrent/synchronization/lockable_object.rb
|
124
|
+
- lib/concurrent/synchronization/mri_lockable_object.rb
|
125
|
+
- lib/concurrent/synchronization/mri_object.rb
|
122
126
|
- lib/concurrent/synchronization/object.rb
|
127
|
+
- lib/concurrent/synchronization/rbx_lockable_object.rb
|
123
128
|
- lib/concurrent/synchronization/rbx_object.rb
|
124
129
|
- lib/concurrent/thread_safe/synchronized_delegator.rb
|
125
130
|
- lib/concurrent/thread_safe/util.rb
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'monitor'
|
2
|
-
require 'concurrent/synchronization/mutex_object'
|
3
|
-
|
4
|
-
module Concurrent
|
5
|
-
module Synchronization
|
6
|
-
|
7
|
-
# @!visibility private
|
8
|
-
# @!macro internal_implementation_note
|
9
|
-
class MonitorObject < MutexObject
|
10
|
-
def initialize
|
11
|
-
@__lock__ = ::Monitor.new
|
12
|
-
@__condition__ = @__lock__.new_cond
|
13
|
-
end
|
14
|
-
|
15
|
-
protected
|
16
|
-
|
17
|
-
def synchronize
|
18
|
-
@__lock__.synchronize { yield }
|
19
|
-
end
|
20
|
-
|
21
|
-
def ns_wait(timeout = nil)
|
22
|
-
@__condition__.wait timeout
|
23
|
-
self
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
module Concurrent
|
2
|
-
module Synchronization
|
3
|
-
|
4
|
-
# @!visibility private
|
5
|
-
# @!macro internal_implementation_note
|
6
|
-
class MutexObject < AbstractObject
|
7
|
-
def initialize
|
8
|
-
@__lock__ = ::Mutex.new
|
9
|
-
@__condition__ = ::ConditionVariable.new
|
10
|
-
end
|
11
|
-
|
12
|
-
protected
|
13
|
-
|
14
|
-
def synchronize
|
15
|
-
if @__lock__.owned?
|
16
|
-
yield
|
17
|
-
else
|
18
|
-
@__lock__.synchronize { yield }
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def ns_signal
|
23
|
-
@__condition__.signal
|
24
|
-
self
|
25
|
-
end
|
26
|
-
|
27
|
-
def ns_broadcast
|
28
|
-
@__condition__.broadcast
|
29
|
-
self
|
30
|
-
end
|
31
|
-
|
32
|
-
def ns_wait(timeout = nil)
|
33
|
-
@__condition__.wait @__lock__, timeout
|
34
|
-
self
|
35
|
-
end
|
36
|
-
|
37
|
-
def ensure_ivar_visibility!
|
38
|
-
# relying on undocumented behavior of CRuby, GVL acquire has lock which ensures visibility of ivars
|
39
|
-
# https://github.com/ruby/ruby/blob/ruby_2_2/thread_pthread.c#L204-L211
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|