concurrent-ruby 1.1.10 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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