concurrent-ruby 1.1.10 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -1
  3. data/Gemfile +0 -1
  4. data/README.md +21 -20
  5. data/Rakefile +53 -63
  6. data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +10 -25
  7. data/lib/concurrent-ruby/concurrent/agent.rb +2 -1
  8. data/lib/concurrent-ruby/concurrent/array.rb +0 -10
  9. data/lib/concurrent-ruby/concurrent/atom.rb +1 -1
  10. data/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb +5 -4
  11. data/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb +5 -4
  12. data/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb +3 -0
  13. data/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +81 -151
  14. data/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb +1 -1
  15. data/lib/concurrent-ruby/concurrent/atomic/event.rb +1 -1
  16. data/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb +109 -0
  17. data/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb +1 -0
  18. data/lib/concurrent-ruby/concurrent/atomic/locals.rb +189 -0
  19. data/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb +28 -0
  20. data/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb +11 -5
  21. data/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb +11 -5
  22. data/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb +1 -1
  23. data/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb +1 -1
  24. data/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb +2 -1
  25. data/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +5 -3
  26. data/lib/concurrent-ruby/concurrent/atomic/semaphore.rb +6 -9
  27. data/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb +96 -89
  28. data/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb +37 -0
  29. data/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb +15 -4
  30. data/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb +1 -1
  31. data/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb +1 -1
  32. data/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb +2 -0
  33. data/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb +2 -2
  34. data/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb +16 -8
  35. data/lib/concurrent-ruby/concurrent/concern/logging.rb +86 -2
  36. data/lib/concurrent-ruby/concurrent/concurrent_ruby.jar +0 -0
  37. data/lib/concurrent-ruby/concurrent/configuration.rb +4 -87
  38. data/lib/concurrent-ruby/concurrent/delay.rb +2 -2
  39. data/lib/concurrent-ruby/concurrent/errors.rb +5 -0
  40. data/lib/concurrent-ruby/concurrent/exchanger.rb +1 -0
  41. data/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb +1 -1
  42. data/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb +2 -2
  43. data/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb +1 -1
  44. data/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb +1 -1
  45. data/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb +4 -1
  46. data/lib/concurrent-ruby/concurrent/hash.rb +0 -9
  47. data/lib/concurrent-ruby/concurrent/immutable_struct.rb +1 -1
  48. data/lib/concurrent-ruby/concurrent/ivar.rb +2 -1
  49. data/lib/concurrent-ruby/concurrent/map.rb +43 -39
  50. data/lib/concurrent-ruby/concurrent/maybe.rb +1 -1
  51. data/lib/concurrent-ruby/concurrent/mutable_struct.rb +1 -1
  52. data/lib/concurrent-ruby/concurrent/mvar.rb +1 -1
  53. data/lib/concurrent-ruby/concurrent/promise.rb +1 -1
  54. data/lib/concurrent-ruby/concurrent/promises.rb +7 -6
  55. data/lib/concurrent-ruby/concurrent/re_include.rb +2 -0
  56. data/lib/concurrent-ruby/concurrent/scheduled_task.rb +1 -1
  57. data/lib/concurrent-ruby/concurrent/set.rb +0 -10
  58. data/lib/concurrent-ruby/concurrent/settable_struct.rb +2 -2
  59. data/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb +5 -1
  60. data/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb +1 -3
  61. data/lib/concurrent-ruby/concurrent/synchronization/condition.rb +2 -0
  62. data/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb +29 -0
  63. data/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb +3 -1
  64. data/lib/concurrent-ruby/concurrent/synchronization/lock.rb +2 -0
  65. data/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb +5 -2
  66. data/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb +6 -5
  67. data/lib/concurrent-ruby/concurrent/synchronization/object.rb +12 -44
  68. data/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb +36 -0
  69. data/lib/concurrent-ruby/concurrent/synchronization/volatile.rb +77 -12
  70. data/lib/concurrent-ruby/concurrent/synchronization.rb +1 -18
  71. data/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb +36 -39
  72. data/lib/concurrent-ruby/concurrent/thread_safe/util/cheap_lockable.rb +2 -39
  73. data/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb +1 -37
  74. data/lib/concurrent-ruby/concurrent/tuple.rb +1 -5
  75. data/lib/concurrent-ruby/concurrent/tvar.rb +2 -1
  76. data/lib/concurrent-ruby/concurrent/utility/engine.rb +5 -16
  77. data/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb +3 -74
  78. data/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb +8 -10
  79. data/lib/concurrent-ruby/concurrent/utility/native_integer.rb +1 -0
  80. data/lib/concurrent-ruby/concurrent/utility/processor_counter.rb +34 -54
  81. data/lib/concurrent-ruby/concurrent/version.rb +1 -1
  82. metadata +13 -15
  83. data/lib/concurrent-ruby/concurrent/atomic/abstract_thread_local_var.rb +0 -66
  84. data/lib/concurrent-ruby/concurrent/atomic/java_thread_local_var.rb +0 -37
  85. data/lib/concurrent-ruby/concurrent/atomic/ruby_thread_local_var.rb +0 -181
  86. data/lib/concurrent-ruby/concurrent/synchronization/jruby_object.rb +0 -45
  87. data/lib/concurrent-ruby/concurrent/synchronization/mri_object.rb +0 -44
  88. data/lib/concurrent-ruby/concurrent/synchronization/rbx_lockable_object.rb +0 -71
  89. data/lib/concurrent-ruby/concurrent/synchronization/rbx_object.rb +0 -49
  90. data/lib/concurrent-ruby/concurrent/synchronization/truffleruby_object.rb +0 -47
@@ -1,102 +1,19 @@
1
1
  require 'thread'
2
2
  require 'concurrent/delay'
3
3
  require 'concurrent/errors'
4
- require 'concurrent/atomic/atomic_reference'
5
- require 'concurrent/concern/logging'
6
4
  require 'concurrent/concern/deprecation'
7
5
  require 'concurrent/executor/immediate_executor'
6
+ require 'concurrent/executor/fixed_thread_pool'
8
7
  require 'concurrent/executor/cached_thread_pool'
9
8
  require 'concurrent/utility/processor_counter'
10
9
 
11
10
  module Concurrent
12
- extend Concern::Logging
13
11
  extend Concern::Deprecation
14
12
 
15
13
  autoload :Options, 'concurrent/options'
16
14
  autoload :TimerSet, 'concurrent/executor/timer_set'
17
15
  autoload :ThreadPoolExecutor, 'concurrent/executor/thread_pool_executor'
18
16
 
19
- # @return [Logger] Logger with provided level and output.
20
- def self.create_simple_logger(level = Logger::FATAL, output = $stderr)
21
- # TODO (pitr-ch 24-Dec-2016): figure out why it had to be replaced, stdlogger was deadlocking
22
- lambda do |severity, progname, message = nil, &block|
23
- return false if severity < level
24
-
25
- message = block ? block.call : message
26
- formatted_message = case message
27
- when String
28
- message
29
- when Exception
30
- format "%s (%s)\n%s",
31
- message.message, message.class, (message.backtrace || []).join("\n")
32
- else
33
- message.inspect
34
- end
35
-
36
- output.print format "[%s] %5s -- %s: %s\n",
37
- Time.now.strftime('%Y-%m-%d %H:%M:%S.%L'),
38
- Logger::SEV_LABEL[severity],
39
- progname,
40
- formatted_message
41
- true
42
- end
43
- end
44
-
45
- # Use logger created by #create_simple_logger to log concurrent-ruby messages.
46
- def self.use_simple_logger(level = Logger::FATAL, output = $stderr)
47
- Concurrent.global_logger = create_simple_logger level, output
48
- end
49
-
50
- # @return [Logger] Logger with provided level and output.
51
- # @deprecated
52
- def self.create_stdlib_logger(level = Logger::FATAL, output = $stderr)
53
- logger = Logger.new(output)
54
- logger.level = level
55
- logger.formatter = lambda do |severity, datetime, progname, msg|
56
- formatted_message = case msg
57
- when String
58
- msg
59
- when Exception
60
- format "%s (%s)\n%s",
61
- msg.message, msg.class, (msg.backtrace || []).join("\n")
62
- else
63
- msg.inspect
64
- end
65
- format "[%s] %5s -- %s: %s\n",
66
- datetime.strftime('%Y-%m-%d %H:%M:%S.%L'),
67
- severity,
68
- progname,
69
- formatted_message
70
- end
71
-
72
- lambda do |loglevel, progname, message = nil, &block|
73
- logger.add loglevel, message, progname, &block
74
- end
75
- end
76
-
77
- # Use logger created by #create_stdlib_logger to log concurrent-ruby messages.
78
- # @deprecated
79
- def self.use_stdlib_logger(level = Logger::FATAL, output = $stderr)
80
- Concurrent.global_logger = create_stdlib_logger level, output
81
- end
82
-
83
- # TODO (pitr-ch 27-Dec-2016): remove deadlocking stdlib_logger methods
84
-
85
- # Suppresses all output when used for logging.
86
- NULL_LOGGER = lambda { |level, progname, message = nil, &block| }
87
-
88
- # @!visibility private
89
- GLOBAL_LOGGER = AtomicReference.new(create_simple_logger(Logger::WARN))
90
- private_constant :GLOBAL_LOGGER
91
-
92
- def self.global_logger
93
- GLOBAL_LOGGER.value
94
- end
95
-
96
- def self.global_logger=(value)
97
- GLOBAL_LOGGER.value = value
98
- end
99
-
100
17
  # @!visibility private
101
18
  GLOBAL_FAST_EXECUTOR = Delay.new { Concurrent.new_fast_executor }
102
19
  private_constant :GLOBAL_FAST_EXECUTOR
@@ -136,14 +53,14 @@ module Concurrent
136
53
  #
137
54
  # @return [ThreadPoolExecutor] the thread pool
138
55
  def self.global_fast_executor
139
- GLOBAL_FAST_EXECUTOR.value
56
+ GLOBAL_FAST_EXECUTOR.value!
140
57
  end
141
58
 
142
59
  # Global thread pool optimized for long, blocking (IO) *tasks*.
143
60
  #
144
61
  # @return [ThreadPoolExecutor] the thread pool
145
62
  def self.global_io_executor
146
- GLOBAL_IO_EXECUTOR.value
63
+ GLOBAL_IO_EXECUTOR.value!
147
64
  end
148
65
 
149
66
  def self.global_immediate_executor
@@ -154,7 +71,7 @@ module Concurrent
154
71
  #
155
72
  # @return [Concurrent::TimerSet] the thread pool
156
73
  def self.global_timer_set
157
- GLOBAL_TIMER_SET.value
74
+ GLOBAL_TIMER_SET.value!
158
75
  end
159
76
 
160
77
  # General access point to global executors.
@@ -1,7 +1,7 @@
1
1
  require 'thread'
2
2
  require 'concurrent/concern/obligation'
3
3
  require 'concurrent/executor/immediate_executor'
4
- require 'concurrent/synchronization'
4
+ require 'concurrent/synchronization/lockable_object'
5
5
 
6
6
  module Concurrent
7
7
 
@@ -67,7 +67,7 @@ module Concurrent
67
67
 
68
68
  # Return the value this object represents after applying the options
69
69
  # specified by the `#set_deref_options` method. If the delayed operation
70
- # raised an exception this method will return nil. The execption object
70
+ # raised an exception this method will return nil. The exception object
71
71
  # can be accessed via the `#reason` method.
72
72
  #
73
73
  # @param [Numeric] timeout the maximum number of seconds to wait
@@ -66,4 +66,9 @@ module Concurrent
66
66
  end
67
67
  end
68
68
 
69
+ # @!macro internal_implementation_note
70
+ class ConcurrentUpdateError < ThreadError
71
+ # frozen pre-allocated backtrace to speed ConcurrentUpdateError
72
+ CONC_UP_ERR_BACKTRACE = ['backtrace elided; set verbose to enable'].freeze
73
+ end
69
74
  end
@@ -289,6 +289,7 @@ module Concurrent
289
289
  end
290
290
 
291
291
  if Concurrent.on_jruby?
292
+ require 'concurrent/utility/native_extension_loader'
292
293
 
293
294
  # @!macro internal_implementation_note
294
295
  # @!visibility private
@@ -1,7 +1,7 @@
1
1
  require 'concurrent/errors'
2
2
  require 'concurrent/concern/deprecation'
3
3
  require 'concurrent/executor/executor_service'
4
- require 'concurrent/synchronization'
4
+ require 'concurrent/synchronization/lockable_object'
5
5
 
6
6
  module Concurrent
7
7
 
@@ -1,7 +1,7 @@
1
- if Concurrent.on_jruby?
1
+ require 'concurrent/utility/engine'
2
2
 
3
+ if Concurrent.on_jruby?
3
4
  require 'concurrent/errors'
4
- require 'concurrent/utility/engine'
5
5
  require 'concurrent/executor/abstract_executor_service'
6
6
 
7
7
  module Concurrent
@@ -1,4 +1,4 @@
1
- require 'concurrent/synchronization'
1
+ require 'concurrent/synchronization/lockable_object'
2
2
 
3
3
  module Concurrent
4
4
 
@@ -1,6 +1,6 @@
1
1
  require 'concurrent/errors'
2
2
  require 'concurrent/concern/logging'
3
- require 'concurrent/synchronization'
3
+ require 'concurrent/synchronization/lockable_object'
4
4
 
5
5
  module Concurrent
6
6
 
@@ -1,5 +1,8 @@
1
- require 'concurrent/atomics'
1
+ require 'concurrent/atomic/atomic_boolean'
2
+ require 'concurrent/atomic/atomic_fixnum'
3
+ require 'concurrent/atomic/event'
2
4
  require 'concurrent/executor/executor_service'
5
+ require 'concurrent/executor/ruby_executor_service'
3
6
 
4
7
  module Concurrent
5
8
 
@@ -28,15 +28,6 @@ module Concurrent
28
28
  end
29
29
  JRubyHash
30
30
 
31
- when Concurrent.on_rbx?
32
- require 'monitor'
33
- require 'concurrent/thread_safe/util/data_structures'
34
-
35
- class RbxHash < ::Hash
36
- end
37
- ThreadSafe::Util.make_synchronized_on_rbx RbxHash
38
- RbxHash
39
-
40
31
  when Concurrent.on_truffleruby?
41
32
  require 'concurrent/thread_safe/util/data_structures'
42
33
 
@@ -1,5 +1,5 @@
1
1
  require 'concurrent/synchronization/abstract_struct'
2
- require 'concurrent/synchronization'
2
+ require 'concurrent/synchronization/lockable_object'
3
3
 
4
4
  module Concurrent
5
5
 
@@ -3,7 +3,8 @@ require 'concurrent/errors'
3
3
  require 'concurrent/collection/copy_on_write_observer_set'
4
4
  require 'concurrent/concern/obligation'
5
5
  require 'concurrent/concern/observable'
6
- require 'concurrent/synchronization'
6
+ require 'concurrent/executor/safe_task_executor'
7
+ require 'concurrent/synchronization/lockable_object'
7
8
 
8
9
  module Concurrent
9
10
 
@@ -1,6 +1,5 @@
1
1
  require 'thread'
2
2
  require 'concurrent/constants'
3
- require 'concurrent/synchronization'
4
3
  require 'concurrent/utility/engine'
5
4
 
6
5
  module Concurrent
@@ -10,17 +9,20 @@ module Concurrent
10
9
  # @!visibility private
11
10
  MapImplementation = case
12
11
  when Concurrent.on_jruby?
12
+ require 'concurrent/utility/native_extension_loader'
13
13
  # noinspection RubyResolve
14
14
  JRubyMapBackend
15
15
  when Concurrent.on_cruby?
16
16
  require 'concurrent/collection/map/mri_map_backend'
17
17
  MriMapBackend
18
- when Concurrent.on_truffleruby? && defined?(::TruffleRuby::ConcurrentMap)
19
- require 'concurrent/collection/map/truffleruby_map_backend'
20
- TruffleRubyMapBackend
21
- when Concurrent.on_truffleruby? || Concurrent.on_rbx?
22
- require 'concurrent/collection/map/atomic_reference_map_backend'
23
- AtomicReferenceMapBackend
18
+ when Concurrent.on_truffleruby?
19
+ if defined?(::TruffleRuby::ConcurrentMap)
20
+ require 'concurrent/collection/map/truffleruby_map_backend'
21
+ TruffleRubyMapBackend
22
+ else
23
+ require 'concurrent/collection/map/atomic_reference_map_backend'
24
+ AtomicReferenceMapBackend
25
+ end
24
26
  else
25
27
  warn 'Concurrent::Map: unsupported Ruby engine, using a fully synchronized Concurrent::Map implementation'
26
28
  require 'concurrent/collection/map/synchronized_map_backend'
@@ -44,6 +46,12 @@ module Concurrent
44
46
  # @note Atomic methods taking a block do not allow the `self` instance
45
47
  # to be used within the block. Doing so will cause a deadlock.
46
48
 
49
+ # @!method []=(key, value)
50
+ # Set a value with key
51
+ # @param [Object] key
52
+ # @param [Object] value
53
+ # @return [Object] the new value
54
+
47
55
  # @!method compute_if_absent(key)
48
56
  # Compute and store new value for key if the key is absent.
49
57
  # @param [Object] key
@@ -117,41 +125,38 @@ module Concurrent
117
125
  # @return [true, false] true if deleted
118
126
  # @!macro map.atomic_method
119
127
 
120
- #
121
- def initialize(options = nil, &block)
122
- if options.kind_of?(::Hash)
123
- validate_options_hash!(options)
124
- else
125
- options = nil
126
- end
128
+ # NonConcurrentMapBackend handles default_proc natively
129
+ unless defined?(Collection::NonConcurrentMapBackend) and self < Collection::NonConcurrentMapBackend
127
130
 
128
- super(options)
129
- @default_proc = block
130
- end
131
+ # @param [Hash, nil] options options to set the :initial_capacity or :load_factor. Ignored on some Rubies.
132
+ # @param [Proc] default_proc Optional block to compute the default value if the key is not set, like `Hash#default_proc`
133
+ def initialize(options = nil, &default_proc)
134
+ if options.kind_of?(::Hash)
135
+ validate_options_hash!(options)
136
+ else
137
+ options = nil
138
+ end
131
139
 
132
- # Get a value with key
133
- # @param [Object] key
134
- # @return [Object] the value
135
- def [](key)
136
- if value = super # non-falsy value is an existing mapping, return it right away
137
- value
138
- # re-check is done with get_or_default(key, NULL) instead of a simple !key?(key) in order to avoid a race condition, whereby by the time the current thread gets to the key?(key) call
139
- # a key => value mapping might have already been created by a different thread (key?(key) would then return true, this elsif branch wouldn't be taken and an incorrent +nil+ value
140
- # would be returned)
141
- # note: nil == value check is not technically necessary
142
- elsif @default_proc && nil == value && NULL == (value = get_or_default(key, NULL))
143
- @default_proc.call(self, key)
144
- else
145
- value
140
+ super(options)
141
+ @default_proc = default_proc
146
142
  end
147
- end
148
143
 
149
- # Set a value with key
150
- # @param [Object] key
151
- # @param [Object] value
152
- # @return [Object] the new value
153
- def []=(key, value)
154
- super
144
+ # Get a value with key
145
+ # @param [Object] key
146
+ # @return [Object] the value
147
+ def [](key)
148
+ if value = super # non-falsy value is an existing mapping, return it right away
149
+ value
150
+ # re-check is done with get_or_default(key, NULL) instead of a simple !key?(key) in order to avoid a race condition, whereby by the time the current thread gets to the key?(key) call
151
+ # a key => value mapping might have already been created by a different thread (key?(key) would then return true, this elsif branch wouldn't be taken and an incorrent +nil+ value
152
+ # would be returned)
153
+ # note: nil == value check is not technically necessary
154
+ elsif @default_proc && nil == value && NULL == (value = get_or_default(key, NULL))
155
+ @default_proc.call(self, key)
156
+ else
157
+ value
158
+ end
159
+ end
155
160
  end
156
161
 
157
162
  alias_method :get, :[]
@@ -197,7 +202,6 @@ module Concurrent
197
202
  # @yieldparam key [Object]
198
203
  # @yieldreturn [Object] default value
199
204
  # @return [Object] the value or default value
200
- # @!macro map.atomic_method_with_block
201
205
  def fetch_or_store(key, default_value = NULL)
202
206
  fetch(key) do
203
207
  put(key, block_given? ? yield(key) : (NULL == default_value ? raise_fetch_no_key : default_value))
@@ -1,4 +1,4 @@
1
- require 'concurrent/synchronization'
1
+ require 'concurrent/synchronization/object'
2
2
 
3
3
  module Concurrent
4
4
 
@@ -1,5 +1,5 @@
1
1
  require 'concurrent/synchronization/abstract_struct'
2
- require 'concurrent/synchronization'
2
+ require 'concurrent/synchronization/lockable_object'
3
3
 
4
4
  module Concurrent
5
5
 
@@ -1,5 +1,5 @@
1
1
  require 'concurrent/concern/dereferenceable'
2
- require 'concurrent/synchronization'
2
+ require 'concurrent/synchronization/object'
3
3
 
4
4
  module Concurrent
5
5
 
@@ -66,7 +66,7 @@ module Concurrent
66
66
  # Start by requiring promises
67
67
  #
68
68
  # ```ruby
69
- # require 'concurrent'
69
+ # require 'concurrent/promise'
70
70
  # ```
71
71
  #
72
72
  # Then create one
@@ -1,7 +1,8 @@
1
- require 'concurrent/synchronization'
1
+ require 'concurrent/synchronization/object'
2
2
  require 'concurrent/atomic/atomic_boolean'
3
3
  require 'concurrent/atomic/atomic_fixnum'
4
4
  require 'concurrent/collection/lock_free_stack'
5
+ require 'concurrent/configuration'
5
6
  require 'concurrent/errors'
6
7
  require 'concurrent/re_include'
7
8
 
@@ -313,7 +314,7 @@ module Concurrent
313
314
  end
314
315
 
315
316
  # @!macro promises.shortcut.on
316
- # @return [Future]
317
+ # @return [Event]
317
318
  def any_event(*futures_and_or_events)
318
319
  any_event_on default_executor, *futures_and_or_events
319
320
  end
@@ -892,7 +893,7 @@ module Concurrent
892
893
  private
893
894
 
894
895
  def rejected_resolution(raise_on_reassign, state)
895
- Concurrent::MultipleAssignmentError.new('Event can be resolved only once') if raise_on_reassign
896
+ raise Concurrent::MultipleAssignmentError.new('Event can be resolved only once') if raise_on_reassign
896
897
  return false
897
898
  end
898
899
 
@@ -1298,7 +1299,7 @@ module Concurrent
1298
1299
 
1299
1300
  # @!macro promise.param.raise_on_reassign
1300
1301
  # @param [Boolean] raise_on_reassign should method raise exception if already resolved
1301
- # @return [self, false] false is returner when raise_on_reassign is false and the receiver
1302
+ # @return [self, false] false is returned when raise_on_reassign is false and the receiver
1302
1303
  # is already resolved.
1303
1304
  #
1304
1305
 
@@ -2074,8 +2075,8 @@ module Concurrent
2074
2075
 
2075
2076
  private
2076
2077
 
2077
- def resolvable?(countdown, future, index)
2078
- future.fulfilled? ||
2078
+ def resolvable?(countdown, event_or_future, index)
2079
+ (event_or_future.is_a?(Event) ? event_or_future.resolved? : event_or_future.fulfilled?) ||
2079
2080
  # inlined super from BlockedPromise
2080
2081
  countdown.zero?
2081
2082
  end
@@ -31,6 +31,8 @@ module Concurrent
31
31
  #
32
32
  # C1.new.respond_to? :a # => false
33
33
  # C2.new.respond_to? :a # => true
34
+ #
35
+ # @!visibility private
34
36
  module ReInclude
35
37
  # @!visibility private
36
38
  def included(base)
@@ -57,7 +57,7 @@ module Concurrent
57
57
  #
58
58
  # @example Basic usage
59
59
  #
60
- # require 'concurrent'
60
+ # require 'concurrent/scheduled_task'
61
61
  # require 'csv'
62
62
  # require 'open-uri'
63
63
  #
@@ -42,16 +42,6 @@ module Concurrent
42
42
 
43
43
  JRubySet
44
44
 
45
- when Concurrent.on_rbx?
46
- require 'monitor'
47
- require 'concurrent/thread_safe/util/data_structures'
48
-
49
- class RbxSet < ::Set
50
- end
51
-
52
- ThreadSafe::Util.make_synchronized_on_rbx RbxSet
53
- RbxSet
54
-
55
45
  when Concurrent.on_truffleruby?
56
46
  require 'concurrent/thread_safe/util/data_structures'
57
47
 
@@ -1,6 +1,6 @@
1
- require 'concurrent/synchronization/abstract_struct'
2
1
  require 'concurrent/errors'
3
- require 'concurrent/synchronization'
2
+ require 'concurrent/synchronization/abstract_struct'
3
+ require 'concurrent/synchronization/lockable_object'
4
4
 
5
5
  module Concurrent
6
6
 
@@ -1,3 +1,7 @@
1
+ require 'concurrent/utility/native_extension_loader' # load native parts first
2
+ require 'concurrent/utility/monotonic_time'
3
+ require 'concurrent/synchronization/object'
4
+
1
5
  module Concurrent
2
6
  module Synchronization
3
7
 
@@ -34,7 +38,7 @@ module Concurrent
34
38
  if timeout
35
39
  wait_until = Concurrent.monotonic_time + timeout
36
40
  loop do
37
- now = Concurrent.monotonic_time
41
+ now = Concurrent.monotonic_time
38
42
  condition_result = condition.call
39
43
  return condition_result if now >= wait_until || condition_result
40
44
  ns_wait wait_until - now
@@ -4,10 +4,8 @@ module Concurrent
4
4
  # @!visibility private
5
5
  # @!macro internal_implementation_note
6
6
  class AbstractObject
7
-
8
- # @abstract has to be implemented based on Ruby runtime
9
7
  def initialize
10
- raise NotImplementedError
8
+ # nothing to do
11
9
  end
12
10
 
13
11
  # @!visibility private
@@ -1,3 +1,5 @@
1
+ require 'concurrent/synchronization/lockable_object'
2
+
1
3
  module Concurrent
2
4
  module Synchronization
3
5
 
@@ -0,0 +1,29 @@
1
+ require 'concurrent/utility/native_extension_loader' # load native parts first
2
+
3
+ module Concurrent
4
+ module Synchronization
5
+ case
6
+ when Concurrent.on_cruby?
7
+ def self.full_memory_barrier
8
+ # relying on undocumented behavior of CRuby, GVL acquire has lock which ensures visibility of ivars
9
+ # https://github.com/ruby/ruby/blob/ruby_2_2/thread_pthread.c#L204-L211
10
+ end
11
+
12
+ when Concurrent.on_jruby?
13
+ require 'concurrent/utility/native_extension_loader'
14
+ def self.full_memory_barrier
15
+ JRubyAttrVolatile.full_memory_barrier
16
+ end
17
+
18
+ when Concurrent.on_truffleruby?
19
+ def self.full_memory_barrier
20
+ TruffleRuby.full_memory_barrier
21
+ end
22
+
23
+ else
24
+ warn 'Possibly unsupported Ruby implementation'
25
+ def self.full_memory_barrier
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,7 +1,9 @@
1
+ require 'concurrent/utility/native_extension_loader' # load native parts first
2
+
1
3
  module Concurrent
2
4
  module Synchronization
3
5
 
4
- if Concurrent.on_jruby? && Concurrent.java_extensions_loaded?
6
+ if Concurrent.on_jruby?
5
7
 
6
8
  # @!visibility private
7
9
  # @!macro internal_implementation_note
@@ -1,3 +1,5 @@
1
+ require 'concurrent/synchronization/lockable_object'
2
+
1
3
  module Concurrent
2
4
  module Synchronization
3
5
 
@@ -1,3 +1,8 @@
1
+ require 'concurrent/utility/engine'
2
+ require 'concurrent/synchronization/abstract_lockable_object'
3
+ require 'concurrent/synchronization/mutex_lockable_object'
4
+ require 'concurrent/synchronization/jruby_lockable_object'
5
+
1
6
  module Concurrent
2
7
  module Synchronization
3
8
 
@@ -8,8 +13,6 @@ module Concurrent
8
13
  MutexLockableObject
9
14
  when Concurrent.on_jruby?
10
15
  JRubyLockableObject
11
- when Concurrent.on_rbx?
12
- RbxLockableObject
13
16
  when Concurrent.on_truffleruby?
14
17
  MutexLockableObject
15
18
  else
@@ -1,5 +1,6 @@
1
+ require 'concurrent/synchronization/abstract_lockable_object'
2
+
1
3
  module Concurrent
2
- # noinspection RubyInstanceVariableNamingConvention
3
4
  module Synchronization
4
5
 
5
6
  # @!visibility private
@@ -26,8 +27,8 @@ module Concurrent
26
27
 
27
28
  safe_initialization!
28
29
 
29
- def initialize(*defaults)
30
- super(*defaults)
30
+ def initialize
31
+ super()
31
32
  @__Lock__ = ::Mutex.new
32
33
  @__Condition__ = ::ConditionVariable.new
33
34
  end
@@ -61,8 +62,8 @@ module Concurrent
61
62
 
62
63
  safe_initialization!
63
64
 
64
- def initialize(*defaults)
65
- super(*defaults)
65
+ def initialize
66
+ super()
66
67
  @__Lock__ = ::Monitor.new
67
68
  @__Condition__ = @__Lock__.new_cond
68
69
  end