concurrent-ruby 0.7.0.rc1-x86-mingw32 → 0.7.0.rc2-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.
- checksums.yaml +8 -8
- data/README.md +3 -2
- data/ext/concurrent_ruby_ext/atomic_boolean.c +48 -0
- data/ext/concurrent_ruby_ext/atomic_boolean.h +16 -0
- data/ext/concurrent_ruby_ext/atomic_fixnum.c +50 -0
- data/ext/concurrent_ruby_ext/atomic_fixnum.h +13 -0
- data/ext/concurrent_ruby_ext/atomic_reference.c +44 -44
- data/ext/concurrent_ruby_ext/atomic_reference.h +8 -0
- data/ext/concurrent_ruby_ext/rb_concurrent.c +32 -3
- data/ext/concurrent_ruby_ext/ruby_193_compatible.h +28 -0
- data/lib/1.9/concurrent_ruby_ext.so +0 -0
- data/lib/2.0/concurrent_ruby_ext.so +0 -0
- data/lib/concurrent.rb +2 -1
- data/lib/concurrent/actor.rb +104 -0
- data/lib/concurrent/{actress → actor}/ad_hoc.rb +2 -3
- data/lib/concurrent/actor/behaviour.rb +70 -0
- data/lib/concurrent/actor/behaviour/abstract.rb +48 -0
- data/lib/concurrent/actor/behaviour/awaits.rb +21 -0
- data/lib/concurrent/actor/behaviour/buffer.rb +54 -0
- data/lib/concurrent/actor/behaviour/errors_on_unknown_message.rb +12 -0
- data/lib/concurrent/actor/behaviour/executes_context.rb +18 -0
- data/lib/concurrent/actor/behaviour/linking.rb +42 -0
- data/lib/concurrent/actor/behaviour/pausing.rb +77 -0
- data/lib/concurrent/actor/behaviour/removes_child.rb +16 -0
- data/lib/concurrent/actor/behaviour/sets_results.rb +36 -0
- data/lib/concurrent/actor/behaviour/supervised.rb +58 -0
- data/lib/concurrent/actor/behaviour/supervising.rb +34 -0
- data/lib/concurrent/actor/behaviour/terminates_children.rb +13 -0
- data/lib/concurrent/actor/behaviour/termination.rb +54 -0
- data/lib/concurrent/actor/context.rb +153 -0
- data/lib/concurrent/actor/core.rb +213 -0
- data/lib/concurrent/actor/default_dead_letter_handler.rb +9 -0
- data/lib/concurrent/{actress → actor}/envelope.rb +1 -1
- data/lib/concurrent/actor/errors.rb +27 -0
- data/lib/concurrent/actor/internal_delegations.rb +49 -0
- data/lib/concurrent/{actress/core_delegations.rb → actor/public_delegations.rb} +11 -13
- data/lib/concurrent/{actress → actor}/reference.rb +25 -8
- data/lib/concurrent/actor/root.rb +37 -0
- data/lib/concurrent/{actress → actor}/type_check.rb +1 -1
- data/lib/concurrent/actor/utills.rb +7 -0
- data/lib/concurrent/actor/utils/broadcast.rb +36 -0
- data/lib/concurrent/actress.rb +2 -224
- data/lib/concurrent/agent.rb +10 -12
- data/lib/concurrent/atomic.rb +32 -1
- data/lib/concurrent/atomic/atomic_boolean.rb +55 -13
- data/lib/concurrent/atomic/atomic_fixnum.rb +54 -16
- data/lib/concurrent/atomic/synchronization.rb +51 -0
- data/lib/concurrent/atomic/thread_local_var.rb +15 -50
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +1 -1
- data/lib/concurrent/atomic_reference/ruby.rb +15 -0
- data/lib/concurrent/atomics.rb +1 -0
- data/lib/concurrent/channel/unbuffered_channel.rb +2 -1
- data/lib/concurrent/configuration.rb +6 -3
- data/lib/concurrent/dataflow.rb +20 -3
- data/lib/concurrent/delay.rb +23 -31
- data/lib/concurrent/executor/executor.rb +7 -2
- data/lib/concurrent/executor/timer_set.rb +1 -1
- data/lib/concurrent/future.rb +2 -1
- data/lib/concurrent/lazy_register.rb +58 -0
- data/lib/concurrent/options_parser.rb +4 -2
- data/lib/concurrent/promise.rb +2 -1
- data/lib/concurrent/scheduled_task.rb +6 -5
- data/lib/concurrent/tvar.rb +6 -10
- data/lib/concurrent/utility/processor_count.rb +4 -2
- data/lib/concurrent/version.rb +1 -1
- data/lib/concurrent_ruby_ext.so +0 -0
- metadata +37 -10
- data/lib/concurrent/actress/context.rb +0 -98
- data/lib/concurrent/actress/core.rb +0 -228
- data/lib/concurrent/actress/errors.rb +0 -14
data/lib/concurrent/agent.rb
CHANGED
@@ -38,10 +38,6 @@ module Concurrent
|
|
38
38
|
include Concurrent::Observable
|
39
39
|
include Logging
|
40
40
|
|
41
|
-
# The default timeout value (in seconds); used when no timeout option
|
42
|
-
# is given at initialization
|
43
|
-
TIMEOUT = 5
|
44
|
-
|
45
41
|
attr_reader :timeout, :task_executor, :operation_executor
|
46
42
|
|
47
43
|
# Initialize a new Agent with the given initial value and provided options.
|
@@ -49,8 +45,6 @@ module Concurrent
|
|
49
45
|
# @param [Object] initial the initial value
|
50
46
|
# @param [Hash] opts the options used to define the behavior at update and deref
|
51
47
|
#
|
52
|
-
# @option opts [Fixnum] :timeout (TIMEOUT) maximum number of seconds before an update is cancelled
|
53
|
-
#
|
54
48
|
# @option opts [Boolean] :operation (false) when `true` will execute the future on the global
|
55
49
|
# operation pool (for long-running operations), when `false` will execute the future on the
|
56
50
|
# global task pool (for short-running tasks)
|
@@ -65,7 +59,6 @@ module Concurrent
|
|
65
59
|
@value = initial
|
66
60
|
@rescuers = []
|
67
61
|
@validator = Proc.new { |result| true }
|
68
|
-
@timeout = opts.fetch(:timeout, TIMEOUT).freeze
|
69
62
|
self.observers = CopyOnWriteObserverSet.new
|
70
63
|
@serialized_execution = SerializedExecution.new
|
71
64
|
@task_executor = OptionsParser.get_task_executor_from(opts)
|
@@ -145,12 +138,19 @@ module Concurrent
|
|
145
138
|
# Update the current value with the result of the given block operation,
|
146
139
|
# block can do blocking calls
|
147
140
|
#
|
141
|
+
# @param [Fixnum, nil] timeout maximum number of seconds before an update is cancelled
|
142
|
+
#
|
148
143
|
# @yield the operation to be performed with the current value in order to calculate
|
149
144
|
# the new value
|
150
145
|
# @yieldparam [Object] value the current value
|
151
146
|
# @yieldreturn [Object] the new value
|
152
147
|
# @return [true, nil] nil when no block is given
|
153
|
-
def post_off(&block)
|
148
|
+
def post_off(timeout = nil, &block)
|
149
|
+
block = if timeout
|
150
|
+
lambda { |value| Concurrent::timeout(timeout) { block.call(value) } }
|
151
|
+
else
|
152
|
+
block
|
153
|
+
end
|
154
154
|
post_on(@operation_executor, &block)
|
155
155
|
end
|
156
156
|
|
@@ -203,10 +203,8 @@ module Concurrent
|
|
203
203
|
validator, value = mutex.synchronize { [@validator, @value] }
|
204
204
|
|
205
205
|
begin
|
206
|
-
result
|
207
|
-
|
208
|
-
[result, validator.call(result)]
|
209
|
-
end
|
206
|
+
result = handler.call(value)
|
207
|
+
valid = validator.call(result)
|
210
208
|
rescue Exception => ex
|
211
209
|
exception = ex
|
212
210
|
end
|
data/lib/concurrent/atomic.rb
CHANGED
@@ -20,7 +20,38 @@ if defined? Concurrent::JavaAtomic
|
|
20
20
|
#
|
21
21
|
# An object reference that may be updated atomically.
|
22
22
|
#
|
23
|
-
#
|
23
|
+
# Testing with ruby 2.1.2
|
24
|
+
#
|
25
|
+
# *** Sequential updates ***
|
26
|
+
# user system total real
|
27
|
+
# no lock 0.000000 0.000000 0.000000 ( 0.005502)
|
28
|
+
# mutex 0.030000 0.000000 0.030000 ( 0.025158)
|
29
|
+
# MutexAtomic 0.100000 0.000000 0.100000 ( 0.103096)
|
30
|
+
# CAtomic 0.040000 0.000000 0.040000 ( 0.034012)
|
31
|
+
#
|
32
|
+
# *** Parallel updates ***
|
33
|
+
# user system total real
|
34
|
+
# no lock 0.010000 0.000000 0.010000 ( 0.009387)
|
35
|
+
# mutex 0.030000 0.010000 0.040000 ( 0.032545)
|
36
|
+
# MutexAtomic 0.830000 2.280000 3.110000 ( 2.146622)
|
37
|
+
# CAtomic 0.040000 0.000000 0.040000 ( 0.038332)
|
38
|
+
#
|
39
|
+
# Testing with jruby 1.9.3
|
40
|
+
#
|
41
|
+
# *** Sequential updates ***
|
42
|
+
# user system total real
|
43
|
+
# no lock 0.170000 0.000000 0.170000 ( 0.051000)
|
44
|
+
# mutex 0.370000 0.010000 0.380000 ( 0.121000)
|
45
|
+
# MutexAtomic 1.530000 0.020000 1.550000 ( 0.471000)
|
46
|
+
# JavaAtomic 0.370000 0.010000 0.380000 ( 0.112000)
|
47
|
+
#
|
48
|
+
# *** Parallel updates ***
|
49
|
+
# user system total real
|
50
|
+
# no lock 0.390000 0.000000 0.390000 ( 0.105000)
|
51
|
+
# mutex 0.480000 0.040000 0.520000 ( 0.145000)
|
52
|
+
# MutexAtomic 1.600000 0.180000 1.780000 ( 0.511000)
|
53
|
+
# JavaAtomic 0.460000 0.010000 0.470000 ( 0.131000)
|
54
|
+
#
|
24
55
|
# @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html
|
25
56
|
# @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html
|
26
57
|
class Concurrent::Atomic < Concurrent::JavaAtomic
|
@@ -6,21 +6,32 @@ module Concurrent
|
|
6
6
|
# boolean and thread-safe and guaranteed to succeed. Reads and writes may block
|
7
7
|
# briefly but no explicit locking is required.
|
8
8
|
#
|
9
|
-
#
|
9
|
+
# Testing with ruby 2.1.2
|
10
|
+
# Testing with Concurrent::MutexAtomicBoolean...
|
11
|
+
# 2.790000 0.000000 2.790000 ( 2.791454)
|
12
|
+
# Testing with Concurrent::CAtomicBoolean...
|
13
|
+
# 0.740000 0.000000 0.740000 ( 0.740206)
|
14
|
+
#
|
15
|
+
# Testing with jruby 1.9.3
|
16
|
+
# Testing with Concurrent::MutexAtomicBoolean...
|
17
|
+
# 5.240000 2.520000 7.760000 ( 3.683000)
|
18
|
+
# Testing with Concurrent::JavaAtomicBoolean...
|
19
|
+
# 3.340000 0.010000 3.350000 ( 0.855000)
|
20
|
+
#
|
10
21
|
# @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html java.util.concurrent.atomic.AtomicBoolean
|
11
22
|
class MutexAtomicBoolean
|
12
23
|
|
13
24
|
# @!macro [attach] atomic_boolean_method_initialize
|
14
25
|
#
|
15
|
-
#
|
26
|
+
# Creates a new `AtomicBoolean` with the given initial value.
|
16
27
|
#
|
17
|
-
#
|
28
|
+
# @param [Boolean] initial the initial value
|
18
29
|
def initialize(initial = false)
|
19
30
|
@value = !!initial
|
20
31
|
@mutex = Mutex.new
|
21
32
|
end
|
22
33
|
|
23
|
-
# @!macro [attach]
|
34
|
+
# @!macro [attach] atomic_boolean_method_value_get
|
24
35
|
#
|
25
36
|
# Retrieves the current `Boolean` value.
|
26
37
|
#
|
@@ -32,7 +43,7 @@ module Concurrent
|
|
32
43
|
@mutex.unlock
|
33
44
|
end
|
34
45
|
|
35
|
-
# @!macro [attach]
|
46
|
+
# @!macro [attach] atomic_boolean_method_value_set
|
36
47
|
#
|
37
48
|
# Explicitly sets the value.
|
38
49
|
#
|
@@ -47,9 +58,9 @@ module Concurrent
|
|
47
58
|
@mutex.unlock
|
48
59
|
end
|
49
60
|
|
50
|
-
# @!macro [attach]
|
61
|
+
# @!macro [attach] atomic_boolean_method_true_question
|
51
62
|
#
|
52
|
-
# Is the current value `true
|
63
|
+
# Is the current value `true`
|
53
64
|
#
|
54
65
|
# @return [Boolean] true if the current value is `true`, else false
|
55
66
|
def true?
|
@@ -59,9 +70,9 @@ module Concurrent
|
|
59
70
|
@mutex.unlock
|
60
71
|
end
|
61
72
|
|
62
|
-
# @!macro
|
73
|
+
# @!macro atomic_boolean_method_false_question
|
63
74
|
#
|
64
|
-
# Is the current value `
|
75
|
+
# Is the current value `false`
|
65
76
|
#
|
66
77
|
# @return [Boolean] true if the current value is `false`, else false
|
67
78
|
def false?
|
@@ -111,24 +122,24 @@ module Concurrent
|
|
111
122
|
@atomic = java.util.concurrent.atomic.AtomicBoolean.new(!!initial)
|
112
123
|
end
|
113
124
|
|
114
|
-
# @!macro
|
125
|
+
# @!macro atomic_boolean_method_value_get
|
115
126
|
#
|
116
127
|
def value
|
117
128
|
@atomic.get
|
118
129
|
end
|
119
130
|
|
120
|
-
# @!macro
|
131
|
+
# @!macro atomic_boolean_method_value_set
|
121
132
|
#
|
122
133
|
def value=(value)
|
123
134
|
@atomic.set(!!value)
|
124
135
|
end
|
125
136
|
|
126
|
-
# @!macro
|
137
|
+
# @!macro atomic_boolean_method_true_question
|
127
138
|
def true?
|
128
139
|
@atomic.get
|
129
140
|
end
|
130
141
|
|
131
|
-
# @!macro
|
142
|
+
# @!macro atomic_boolean_method_false_question
|
132
143
|
def false?
|
133
144
|
!@atomic.get
|
134
145
|
end
|
@@ -148,6 +159,37 @@ module Concurrent
|
|
148
159
|
class AtomicBoolean < JavaAtomicBoolean
|
149
160
|
end
|
150
161
|
|
162
|
+
elsif defined? Concurrent::CAtomicBoolean
|
163
|
+
|
164
|
+
# @!macro atomic_boolean
|
165
|
+
class CAtomicBoolean
|
166
|
+
|
167
|
+
# @!method initialize
|
168
|
+
# @!macro atomic_boolean_method_initialize
|
169
|
+
|
170
|
+
# @!method value
|
171
|
+
# @!macro atomic_boolean_method_value_get
|
172
|
+
|
173
|
+
# @!method value=
|
174
|
+
# @!macro atomic_boolean_method_value_set
|
175
|
+
|
176
|
+
# @!method true?
|
177
|
+
# @!macro atomic_boolean_method_true_question
|
178
|
+
|
179
|
+
# @!method false?
|
180
|
+
# @!macro atomic_boolean_method_false_question
|
181
|
+
|
182
|
+
# @!method make_true
|
183
|
+
# @!macro atomic_boolean_method_make_true
|
184
|
+
|
185
|
+
# @!method make_false
|
186
|
+
# @!macro atomic_boolean_method_make_false
|
187
|
+
end
|
188
|
+
|
189
|
+
# @!macro atomic_boolean
|
190
|
+
class AtomicBoolean < CAtomicBoolean
|
191
|
+
end
|
192
|
+
|
151
193
|
else
|
152
194
|
|
153
195
|
# @!macro atomic_boolean
|
@@ -6,23 +6,38 @@ module Concurrent
|
|
6
6
|
# fixnum and thread-safe and guaranteed to succeed. Reads and writes may block
|
7
7
|
# briefly but no explicit locking is required.
|
8
8
|
#
|
9
|
-
#
|
9
|
+
# Testing with ruby 2.1.2
|
10
|
+
# Testing with Concurrent::MutexAtomicFixnum...
|
11
|
+
# 3.130000 0.000000 3.130000 ( 3.136505)
|
12
|
+
# Testing with Concurrent::CAtomicFixnum...
|
13
|
+
# 0.790000 0.000000 0.790000 ( 0.785550)
|
14
|
+
#
|
15
|
+
# Testing with jruby 1.9.3
|
16
|
+
# Testing with Concurrent::MutexAtomicFixnum...
|
17
|
+
# 5.460000 2.460000 7.920000 ( 3.715000)
|
18
|
+
# Testing with Concurrent::JavaAtomicFixnum...
|
19
|
+
# 4.520000 0.030000 4.550000 ( 1.187000)
|
20
|
+
#
|
10
21
|
# @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicLong.html java.util.concurrent.atomic.AtomicLong
|
11
22
|
class MutexAtomicFixnum
|
12
23
|
|
24
|
+
# http://stackoverflow.com/questions/535721/ruby-max-integer
|
25
|
+
MIN_VALUE = -(2**(0.size * 8 -2))
|
26
|
+
MAX_VALUE = (2**(0.size * 8 -2) -1)
|
27
|
+
|
13
28
|
# @!macro [attach] atomic_fixnum_method_initialize
|
14
29
|
#
|
15
|
-
#
|
30
|
+
# Creates a new `AtomicFixnum` with the given initial value.
|
16
31
|
#
|
17
|
-
#
|
18
|
-
#
|
32
|
+
# @param [Fixnum] init the initial value
|
33
|
+
# @raise [ArgumentError] if the initial value is not a `Fixnum`
|
19
34
|
def initialize(init = 0)
|
20
35
|
raise ArgumentError.new('initial value must be a Fixnum') unless init.is_a?(Fixnum)
|
21
36
|
@value = init
|
22
37
|
@mutex = Mutex.new
|
23
38
|
end
|
24
39
|
|
25
|
-
# @!macro [attach]
|
40
|
+
# @!macro [attach] atomic_fixnum_method_value_get
|
26
41
|
#
|
27
42
|
# Retrieves the current `Fixnum` value.
|
28
43
|
#
|
@@ -34,7 +49,7 @@ module Concurrent
|
|
34
49
|
@mutex.unlock
|
35
50
|
end
|
36
51
|
|
37
|
-
# @!macro [attach]
|
52
|
+
# @!macro [attach] atomic_fixnum_method_value_set
|
38
53
|
#
|
39
54
|
# Explicitly sets the value.
|
40
55
|
#
|
@@ -106,44 +121,39 @@ module Concurrent
|
|
106
121
|
# @!macro atomic_fixnum
|
107
122
|
class JavaAtomicFixnum
|
108
123
|
|
124
|
+
MIN_VALUE = Java::JavaLang::Long::MIN_VALUE
|
125
|
+
MAX_VALUE = Java::JavaLang::Long::MAX_VALUE
|
126
|
+
|
109
127
|
# @!macro atomic_fixnum_method_initialize
|
110
|
-
#
|
111
128
|
def initialize(init = 0)
|
112
129
|
raise ArgumentError.new('initial value must be a Fixnum') unless init.is_a?(Fixnum)
|
113
130
|
@atomic = java.util.concurrent.atomic.AtomicLong.new(init)
|
114
131
|
end
|
115
132
|
|
116
|
-
# @!macro
|
117
|
-
#
|
133
|
+
# @!macro atomic_fixnum_method_value_get
|
118
134
|
def value
|
119
135
|
@atomic.get
|
120
136
|
end
|
121
137
|
|
122
|
-
# @!macro
|
123
|
-
#
|
138
|
+
# @!macro atomic_fixnum_method_value_set
|
124
139
|
def value=(value)
|
125
140
|
raise ArgumentError.new('value must be a Fixnum') unless value.is_a?(Fixnum)
|
126
141
|
@atomic.set(value)
|
127
142
|
end
|
128
143
|
|
129
144
|
# @!macro atomic_fixnum_method_increment
|
130
|
-
#
|
131
145
|
def increment
|
132
146
|
@atomic.increment_and_get
|
133
147
|
end
|
134
|
-
|
135
148
|
alias_method :up, :increment
|
136
149
|
|
137
150
|
# @!macro atomic_fixnum_method_decrement
|
138
|
-
#
|
139
151
|
def decrement
|
140
152
|
@atomic.decrement_and_get
|
141
153
|
end
|
142
|
-
|
143
154
|
alias_method :down, :decrement
|
144
155
|
|
145
156
|
# @!macro atomic_fixnum_method_compare_and_set
|
146
|
-
#
|
147
157
|
def compare_and_set(expect, update)
|
148
158
|
@atomic.compare_and_set(expect, update)
|
149
159
|
end
|
@@ -153,6 +163,34 @@ module Concurrent
|
|
153
163
|
class AtomicFixnum < JavaAtomicFixnum
|
154
164
|
end
|
155
165
|
|
166
|
+
elsif defined? Concurrent::CAtomicFixnum
|
167
|
+
|
168
|
+
# @!macro atomic_fixnum
|
169
|
+
class CAtomicFixnum
|
170
|
+
|
171
|
+
# @!method initialize
|
172
|
+
# @!macro atomic_fixnum_method_initialize
|
173
|
+
|
174
|
+
# @!method value
|
175
|
+
# @!macro atomic_fixnum_method_value_get
|
176
|
+
|
177
|
+
# @!method value=
|
178
|
+
# @!macro atomic_fixnum_method_value_set
|
179
|
+
|
180
|
+
# @!method increment
|
181
|
+
# @!macro atomic_fixnum_method_increment
|
182
|
+
|
183
|
+
# @!method decrement
|
184
|
+
# @!macro atomic_fixnum_method_decrement
|
185
|
+
|
186
|
+
# @!method compare_and_set
|
187
|
+
# @!macro atomic_fixnum_method_compare_and_set
|
188
|
+
end
|
189
|
+
|
190
|
+
# @!macro atomic_fixnum
|
191
|
+
class AtomicFixnum < CAtomicFixnum
|
192
|
+
end
|
193
|
+
|
156
194
|
else
|
157
195
|
|
158
196
|
# @!macro atomic_fixnum
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Concurrent
|
2
|
+
|
3
|
+
# Safe synchronization under JRuby, prevents reading uninitialized @mutex variable.
|
4
|
+
# @note synchronized needs to be called in #initialize for this module to work properly
|
5
|
+
# @example usage
|
6
|
+
# class AClass
|
7
|
+
# include Synchronized
|
8
|
+
#
|
9
|
+
# def initialize
|
10
|
+
# synchronize do
|
11
|
+
# # body of the constructor ...
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# def a_method
|
16
|
+
# synchronize do
|
17
|
+
# # body of a_method ...
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
module Synchronization
|
22
|
+
|
23
|
+
engine = defined?(RUBY_ENGINE) && RUBY_ENGINE
|
24
|
+
|
25
|
+
case engine
|
26
|
+
when 'jruby'
|
27
|
+
require 'jruby'
|
28
|
+
|
29
|
+
def synchronize
|
30
|
+
JRuby.reference0(self).synchronized { yield }
|
31
|
+
end
|
32
|
+
|
33
|
+
when 'rbx'
|
34
|
+
|
35
|
+
def synchronize
|
36
|
+
Rubinius.lock(self)
|
37
|
+
yield
|
38
|
+
ensure
|
39
|
+
Rubinius.unlock(self)
|
40
|
+
end
|
41
|
+
|
42
|
+
else
|
43
|
+
|
44
|
+
def synchronize
|
45
|
+
@mutex ||= Mutex.new
|
46
|
+
@mutex.synchronize { yield }
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,54 +1,19 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
module ThreadLocalSymbolAllocator
|
4
|
-
|
5
|
-
COUNTER = AtomicFixnum.new
|
6
|
-
|
7
|
-
protected
|
8
|
-
|
9
|
-
def allocate_symbol
|
10
|
-
# Warning: this symbol may never be deallocated
|
11
|
-
@symbol = :"thread_local_symbol_#{COUNTER.increment}"
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
module ThreadLocalOldStorage
|
17
|
-
|
18
|
-
include ThreadLocalSymbolAllocator
|
19
|
-
|
20
|
-
protected
|
21
|
-
|
22
|
-
def allocate_storage
|
23
|
-
allocate_symbol
|
24
|
-
end
|
25
|
-
|
26
|
-
def get
|
27
|
-
Thread.current[@symbol]
|
28
|
-
end
|
1
|
+
require 'concurrent/atomic'
|
29
2
|
|
30
|
-
|
31
|
-
Thread.current[@symbol] = value
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
module ThreadLocalNewStorage
|
37
|
-
|
38
|
-
include ThreadLocalSymbolAllocator
|
3
|
+
module Concurrent
|
39
4
|
|
40
|
-
|
5
|
+
module ThreadLocalRubyStorage
|
41
6
|
|
42
7
|
def allocate_storage
|
43
|
-
|
8
|
+
@storage = Atomic.new Hash.new
|
44
9
|
end
|
45
10
|
|
46
11
|
def get
|
47
|
-
Thread.current
|
12
|
+
@storage.get[Thread.current]
|
48
13
|
end
|
49
14
|
|
50
15
|
def set(value)
|
51
|
-
Thread.current
|
16
|
+
@storage.update { |s| s.merge Thread.current => value }
|
52
17
|
end
|
53
18
|
|
54
19
|
end
|
@@ -71,18 +36,10 @@ module Concurrent
|
|
71
36
|
|
72
37
|
end
|
73
38
|
|
74
|
-
class
|
39
|
+
class AbstractThreadLocalVar
|
75
40
|
|
76
41
|
NIL_SENTINEL = Object.new
|
77
42
|
|
78
|
-
if RUBY_PLATFORM == 'java'
|
79
|
-
include ThreadLocalJavaStorage
|
80
|
-
elsif Thread.current.respond_to?(:thread_variable_set)
|
81
|
-
include ThreadLocalNewStorage
|
82
|
-
else
|
83
|
-
include ThreadLocalOldStorage
|
84
|
-
end
|
85
|
-
|
86
43
|
def initialize(default = nil)
|
87
44
|
@default = default
|
88
45
|
allocate_storage
|
@@ -114,4 +71,12 @@ module Concurrent
|
|
114
71
|
|
115
72
|
end
|
116
73
|
|
74
|
+
class ThreadLocalVar < AbstractThreadLocalVar
|
75
|
+
if RUBY_PLATFORM == 'java'
|
76
|
+
include ThreadLocalJavaStorage
|
77
|
+
else
|
78
|
+
include ThreadLocalRubyStorage
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
117
82
|
end
|