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
@@ -9,7 +9,7 @@ module Concurrent
|
|
9
9
|
include Concurrent::AtomicDirectUpdate
|
10
10
|
include Concurrent::AtomicNumericCompareAndSetWrapper
|
11
11
|
|
12
|
-
# @!macro atomic_reference_method_initialize
|
12
|
+
# @!macro [attach] atomic_reference_method_initialize
|
13
13
|
def initialize(value = nil)
|
14
14
|
@mutex = Mutex.new
|
15
15
|
@value = value
|
@@ -14,5 +14,20 @@ module Concurrent
|
|
14
14
|
class CAtomic
|
15
15
|
include Concurrent::AtomicDirectUpdate
|
16
16
|
include Concurrent::AtomicNumericCompareAndSetWrapper
|
17
|
+
|
18
|
+
# @!method initialize
|
19
|
+
# @!macro atomic_reference_method_initialize
|
20
|
+
|
21
|
+
# @!method get
|
22
|
+
# @!macro atomic_reference_method_get
|
23
|
+
|
24
|
+
# @!method set
|
25
|
+
# @!macro atomic_reference_method_set
|
26
|
+
|
27
|
+
# @!method get_and_set
|
28
|
+
# @!macro atomic_reference_method_get_and_set
|
29
|
+
|
30
|
+
# @!method _compare_and_set
|
31
|
+
# @!macro atomic_reference_method_compare_and_set
|
17
32
|
end
|
18
33
|
end
|
data/lib/concurrent/atomics.rb
CHANGED
@@ -12,6 +12,7 @@ module Concurrent
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def push(value)
|
15
|
+
# TODO set_unless_assigned define on IVar as #set_state? or #try_set_state
|
15
16
|
until @probe_set.take.set_unless_assigned(value, self)
|
16
17
|
end
|
17
18
|
end
|
@@ -31,4 +32,4 @@ module Concurrent
|
|
31
32
|
end
|
32
33
|
|
33
34
|
end
|
34
|
-
end
|
35
|
+
end
|
@@ -2,6 +2,7 @@ require 'thread'
|
|
2
2
|
require 'concurrent/delay'
|
3
3
|
require 'concurrent/errors'
|
4
4
|
require 'concurrent/atomic'
|
5
|
+
require 'concurrent/executor/immediate_executor'
|
5
6
|
require 'concurrent/executor/thread_pool_executor'
|
6
7
|
require 'concurrent/executor/timer_set'
|
7
8
|
require 'concurrent/utility/processor_count'
|
@@ -18,9 +19,10 @@ module Concurrent
|
|
18
19
|
|
19
20
|
# Create a new configuration object.
|
20
21
|
def initialize
|
21
|
-
|
22
|
-
@
|
23
|
-
@
|
22
|
+
immediate_executor = ImmediateExecutor.new
|
23
|
+
@global_task_pool = Delay.new(executor: immediate_executor) { new_task_pool }
|
24
|
+
@global_operation_pool = Delay.new(executor: immediate_executor) { new_operation_pool }
|
25
|
+
@global_timer_set = Delay.new(executor: immediate_executor) { Concurrent::TimerSet.new }
|
24
26
|
@logger = no_logger
|
25
27
|
end
|
26
28
|
|
@@ -154,5 +156,6 @@ module Concurrent
|
|
154
156
|
self.finalize_executor(self.configuration.global_timer_set)
|
155
157
|
self.finalize_executor(self.configuration.global_task_pool)
|
156
158
|
self.finalize_executor(self.configuration.global_operation_pool)
|
159
|
+
# TODO may break other test suites using concurrent-ruby, terminates before test is run
|
157
160
|
end
|
158
161
|
end
|
data/lib/concurrent/dataflow.rb
CHANGED
@@ -61,17 +61,34 @@ module Concurrent
|
|
61
61
|
# @raise [ArgumentError] if no block is given
|
62
62
|
# @raise [ArgumentError] if any of the inputs are not `IVar`s
|
63
63
|
def dataflow(*inputs, &block)
|
64
|
-
dataflow_with(Concurrent.configuration.
|
64
|
+
dataflow_with(Concurrent.configuration.global_operation_pool, *inputs, &block)
|
65
65
|
end
|
66
66
|
module_function :dataflow
|
67
67
|
|
68
68
|
def dataflow_with(executor, *inputs, &block)
|
69
|
+
call_dataflow(:value, executor, *inputs, &block)
|
70
|
+
end
|
71
|
+
module_function :dataflow_with
|
72
|
+
|
73
|
+
def dataflow!(*inputs, &block)
|
74
|
+
dataflow_with!(Concurrent.configuration.global_task_pool, *inputs, &block)
|
75
|
+
end
|
76
|
+
module_function :dataflow!
|
77
|
+
|
78
|
+
def dataflow_with!(executor, *inputs, &block)
|
79
|
+
call_dataflow(:value!, executor, *inputs, &block)
|
80
|
+
end
|
81
|
+
module_function :dataflow_with!
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def call_dataflow(method, executor, *inputs, &block)
|
69
86
|
raise ArgumentError.new('an executor must be provided') if executor.nil?
|
70
87
|
raise ArgumentError.new('no block given') unless block_given?
|
71
88
|
raise ArgumentError.new('not all dependencies are IVars') unless inputs.all? { |input| input.is_a? IVar }
|
72
89
|
|
73
90
|
result = Future.new(executor: executor) do
|
74
|
-
values = inputs.map { |input| input.
|
91
|
+
values = inputs.map { |input| input.send(method) }
|
75
92
|
block.call(*values)
|
76
93
|
end
|
77
94
|
|
@@ -87,5 +104,5 @@ module Concurrent
|
|
87
104
|
|
88
105
|
result
|
89
106
|
end
|
90
|
-
module_function :
|
107
|
+
module_function :call_dataflow
|
91
108
|
end
|
data/lib/concurrent/delay.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'thread'
|
2
2
|
require 'concurrent/obligation'
|
3
|
+
require 'concurrent/options_parser'
|
3
4
|
|
4
5
|
module Concurrent
|
5
6
|
|
@@ -51,32 +52,13 @@ module Concurrent
|
|
51
52
|
@state = :pending
|
52
53
|
@task = block
|
53
54
|
set_deref_options(opts)
|
55
|
+
@task_executor = OptionsParser.get_task_executor_from(opts)
|
56
|
+
@computing = false
|
54
57
|
end
|
55
58
|
|
56
|
-
|
57
|
-
#
|
58
|
-
# If the state is `:pending` then the calling thread will block while the
|
59
|
-
# operation is performed. All other threads simultaneously calling `#value`
|
60
|
-
# will block as well. Once the operation is complete (either `:fulfilled` or
|
61
|
-
# `:rejected`) all waiting threads will unblock and the new value will be
|
62
|
-
# returned.
|
63
|
-
#
|
64
|
-
# If the state is not `:pending` when `#value` is called the (possibly memoized)
|
65
|
-
# value will be returned without blocking and without performing the operation
|
66
|
-
# again.
|
67
|
-
#
|
68
|
-
# Regardless of the final disposition all `Dereferenceable` options set during
|
69
|
-
# object construction will be honored.
|
70
|
-
#
|
71
|
-
# @return [Object] the (possibly memoized) result of the block operation
|
72
|
-
#
|
73
|
-
# @see Concurrent::Dereferenceable
|
74
|
-
def value
|
75
|
-
mutex.lock
|
59
|
+
def wait(timeout)
|
76
60
|
execute_task_once
|
77
|
-
|
78
|
-
ensure
|
79
|
-
mutex.unlock
|
61
|
+
super timeout
|
80
62
|
end
|
81
63
|
|
82
64
|
# reconfigures the block returning the value if still #incomplete?
|
@@ -85,7 +67,7 @@ module Concurrent
|
|
85
67
|
def reconfigure(&block)
|
86
68
|
mutex.lock
|
87
69
|
raise ArgumentError.new('no block given') unless block_given?
|
88
|
-
|
70
|
+
unless @computing
|
89
71
|
@task = block
|
90
72
|
true
|
91
73
|
else
|
@@ -98,13 +80,23 @@ module Concurrent
|
|
98
80
|
private
|
99
81
|
|
100
82
|
def execute_task_once
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
83
|
+
mutex.lock
|
84
|
+
execute = @computing = true unless @computing
|
85
|
+
task = @task
|
86
|
+
mutex.unlock
|
87
|
+
|
88
|
+
if execute
|
89
|
+
@task_executor.post do
|
90
|
+
begin
|
91
|
+
result = task.call
|
92
|
+
success = true
|
93
|
+
rescue => ex
|
94
|
+
reason = ex
|
95
|
+
end
|
96
|
+
mutex.lock
|
97
|
+
set_state success, result, reason
|
98
|
+
event.set
|
99
|
+
mutex.unlock
|
108
100
|
end
|
109
101
|
end
|
110
102
|
end
|
@@ -250,8 +250,13 @@ module Concurrent
|
|
250
250
|
end
|
251
251
|
|
252
252
|
# @!macro executor_method_wait_for_termination
|
253
|
-
def wait_for_termination(timeout)
|
254
|
-
|
253
|
+
def wait_for_termination(timeout = nil)
|
254
|
+
if timeout.nil?
|
255
|
+
ok = @executor.awaitTermination(60, java.util.concurrent.TimeUnit::SECONDS) until ok
|
256
|
+
true
|
257
|
+
else
|
258
|
+
@executor.awaitTermination(1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS)
|
259
|
+
end
|
255
260
|
end
|
256
261
|
|
257
262
|
# @!macro executor_method_shutdown
|
@@ -23,7 +23,7 @@ module Concurrent
|
|
23
23
|
# this executor rather than the global thread pool (overrides :operation)
|
24
24
|
def initialize(opts = {})
|
25
25
|
@queue = PriorityQueue.new(order: :min)
|
26
|
-
@task_executor = OptionsParser::get_executor_from(opts)
|
26
|
+
@task_executor = OptionsParser::get_executor_from(opts) || Concurrent.configuration.global_task_pool
|
27
27
|
@timer_executor = SingleThreadExecutor.new
|
28
28
|
@condition = Condition.new
|
29
29
|
init_executor
|
data/lib/concurrent/future.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'thread'
|
2
2
|
|
3
3
|
require 'concurrent/options_parser'
|
4
|
+
require 'concurrent/ivar'
|
4
5
|
require 'concurrent/executor/safe_task_executor'
|
5
6
|
|
6
7
|
module Concurrent
|
@@ -61,7 +62,7 @@ module Concurrent
|
|
61
62
|
super(IVar::NO_VALUE, opts)
|
62
63
|
@state = :unscheduled
|
63
64
|
@task = block
|
64
|
-
@executor = OptionsParser::get_executor_from(opts)
|
65
|
+
@executor = OptionsParser::get_executor_from(opts) || Concurrent.configuration.global_operation_pool
|
65
66
|
end
|
66
67
|
|
67
68
|
# Execute an `:unscheduled` `Future`. Immediately sets the state to `:pending` and
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'concurrent/atomic'
|
2
|
+
require 'concurrent/delay'
|
3
|
+
|
4
|
+
|
5
|
+
module Concurrent
|
6
|
+
# Allows to store lazy evaluated values under keys. Uses `Delay`s.
|
7
|
+
# @example
|
8
|
+
# register = Concurrent::LazyRegister.new
|
9
|
+
# #=> #<Concurrent::LazyRegister:0x007fd7ecd5e230 @data=#<Concurrent::Atomic:0x007fd7ecd5e1e0>>
|
10
|
+
# register[:key]
|
11
|
+
# #=> nil
|
12
|
+
# register.add(:key) { Concurrent::Actor.spawn!(Actor::AdHoc, :ping) { -> message { message } } }
|
13
|
+
# #=> #<Concurrent::LazyRegister:0x007fd7ecd5e230 @data=#<Concurrent::Atomic:0x007fd7ecd5e1e0>>
|
14
|
+
# register[:key]
|
15
|
+
# #=> #<Concurrent::Actor::Reference /ping (Concurrent::Actor::AdHoc)>
|
16
|
+
class LazyRegister
|
17
|
+
def initialize
|
18
|
+
@data = Atomic.new Hash.new
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param [Object] key
|
22
|
+
# @return value stored under the key
|
23
|
+
# @raise Exception when the initialization block fails
|
24
|
+
def [](key)
|
25
|
+
delay = @data.get[key]
|
26
|
+
delay.value! if delay
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param [Object] key
|
30
|
+
# @return [true, false] if the key is registered
|
31
|
+
def registered?(key)
|
32
|
+
@data.get.key? key
|
33
|
+
end
|
34
|
+
|
35
|
+
alias_method :key?, :registered?
|
36
|
+
|
37
|
+
# @param [Object] key
|
38
|
+
# @yield the object to store under the key
|
39
|
+
# @return self
|
40
|
+
def register(key, &block)
|
41
|
+
delay = Delay.new(&block)
|
42
|
+
@data.update { |h| h.merge key => delay }
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
alias_method :add, :register
|
47
|
+
|
48
|
+
# Un-registers the object under key, realized or not
|
49
|
+
# @return self
|
50
|
+
# @param [Object] key
|
51
|
+
def unregister(key)
|
52
|
+
@data.update { |h| h.dup.tap { |h| h.delete(key) } }
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
alias_method :remove, :unregister
|
57
|
+
end
|
58
|
+
end
|
@@ -10,14 +10,16 @@ module Concurrent
|
|
10
10
|
# @option opts [Boolean] :operation (`false`) when true use the global operation pool
|
11
11
|
# @option opts [Boolean] :task (`true`) when true use the global task pool
|
12
12
|
#
|
13
|
-
# @return [Executor] the requested thread pool
|
13
|
+
# @return [Executor, nil] the requested thread pool, or nil when no option specified
|
14
14
|
def get_executor_from(opts = {})
|
15
15
|
if opts[:executor]
|
16
16
|
opts[:executor]
|
17
17
|
elsif opts[:operation] == true || opts[:task] == false
|
18
18
|
Concurrent.configuration.global_operation_pool
|
19
|
-
|
19
|
+
elsif opts[:operation] == false || opts[:task] == true
|
20
20
|
Concurrent.configuration.global_task_pool
|
21
|
+
else
|
22
|
+
nil
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
data/lib/concurrent/promise.rb
CHANGED
@@ -5,6 +5,7 @@ require 'concurrent/options_parser'
|
|
5
5
|
|
6
6
|
module Concurrent
|
7
7
|
|
8
|
+
# TODO unify promise and future to single class, with dataflow
|
8
9
|
class Promise
|
9
10
|
include Obligation
|
10
11
|
|
@@ -32,7 +33,7 @@ module Concurrent
|
|
32
33
|
def initialize(opts = {}, &block)
|
33
34
|
opts.delete_if { |k, v| v.nil? }
|
34
35
|
|
35
|
-
@executor = OptionsParser::get_executor_from(opts)
|
36
|
+
@executor = OptionsParser::get_executor_from(opts) || Concurrent.configuration.global_operation_pool
|
36
37
|
@parent = opts.fetch(:parent) { nil }
|
37
38
|
@on_fulfill = opts.fetch(:on_fulfill) { Proc.new { |result| result } }
|
38
39
|
@on_reject = opts.fetch(:on_reject) { Proc.new { |reason| raise reason } }
|
@@ -15,16 +15,17 @@ module Concurrent
|
|
15
15
|
super(NO_VALUE, opts)
|
16
16
|
|
17
17
|
self.observers = CopyOnNotifyObserverSet.new
|
18
|
-
@intended_time =
|
19
|
-
@state
|
20
|
-
@task
|
18
|
+
@intended_time = intended_time
|
19
|
+
@state = :unscheduled
|
20
|
+
@task = block
|
21
|
+
@executor = OptionsParser::get_executor_from(opts) || Concurrent.configuration.global_operation_pool
|
21
22
|
end
|
22
23
|
|
23
24
|
# @since 0.5.0
|
24
25
|
def execute
|
25
26
|
if compare_and_set_state(:pending, :unscheduled)
|
26
27
|
@schedule_time = TimerSet.calculate_schedule_time(@intended_time)
|
27
|
-
Concurrent::timer(@schedule_time.to_f - Time.now.to_f
|
28
|
+
Concurrent::timer(@schedule_time.to_f - Time.now.to_f) { @executor.post &method(:process_task) }
|
28
29
|
self
|
29
30
|
end
|
30
31
|
end
|
@@ -71,7 +72,7 @@ module Concurrent
|
|
71
72
|
end
|
72
73
|
|
73
74
|
time = Time.now
|
74
|
-
observers.notify_and_delete_observers{ [time, self.value, reason] }
|
75
|
+
observers.notify_and_delete_observers { [time, self.value, reason] }
|
75
76
|
end
|
76
77
|
end
|
77
78
|
end
|
data/lib/concurrent/tvar.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
require 'set'
|
2
2
|
|
3
|
-
require 'concurrent/atomic/thread_local_var'
|
4
|
-
|
5
3
|
module Concurrent
|
6
4
|
|
7
5
|
# A `TVar` is a transactional variable - a single-element container that
|
@@ -97,7 +95,7 @@ module Concurrent
|
|
97
95
|
|
98
96
|
begin
|
99
97
|
# Retry loop
|
100
|
-
|
98
|
+
|
101
99
|
loop do
|
102
100
|
|
103
101
|
# Create a new transaction
|
@@ -149,8 +147,6 @@ module Concurrent
|
|
149
147
|
|
150
148
|
ABORTED = Object.new
|
151
149
|
|
152
|
-
CURRENT_TRANSACTION = ThreadLocalVar.new(nil)
|
153
|
-
|
154
150
|
ReadLogEntry = Struct.new(:tvar, :version)
|
155
151
|
UndoLogEntry = Struct.new(:tvar, :value)
|
156
152
|
|
@@ -158,8 +154,8 @@ module Concurrent
|
|
158
154
|
|
159
155
|
def initialize
|
160
156
|
@write_set = Set.new
|
161
|
-
@read_log
|
162
|
-
@undo_log
|
157
|
+
@read_log = []
|
158
|
+
@undo_log = []
|
163
159
|
end
|
164
160
|
|
165
161
|
def read(tvar)
|
@@ -217,7 +213,7 @@ module Concurrent
|
|
217
213
|
end
|
218
214
|
|
219
215
|
unlock
|
220
|
-
|
216
|
+
|
221
217
|
true
|
222
218
|
end
|
223
219
|
|
@@ -240,11 +236,11 @@ module Concurrent
|
|
240
236
|
end
|
241
237
|
|
242
238
|
def self.current
|
243
|
-
|
239
|
+
Thread.current[:current_tvar_transaction]
|
244
240
|
end
|
245
241
|
|
246
242
|
def self.current=(transaction)
|
247
|
-
|
243
|
+
Thread.current[:current_tvar_transaction] = transaction
|
248
244
|
end
|
249
245
|
|
250
246
|
end
|
@@ -1,12 +1,14 @@
|
|
1
1
|
require 'rbconfig'
|
2
2
|
require 'concurrent/delay'
|
3
|
+
require 'concurrent/executor/immediate_executor'
|
3
4
|
|
4
5
|
module Concurrent
|
5
6
|
|
6
7
|
class ProcessorCounter
|
7
8
|
def initialize
|
8
|
-
|
9
|
-
@
|
9
|
+
immediate_executor = ImmediateExecutor.new
|
10
|
+
@processor_count = Delay.new(executor: immediate_executor) { compute_processor_count }
|
11
|
+
@physical_processor_count = Delay.new(executor: immediate_executor) { compute_physical_processor_count }
|
10
12
|
end
|
11
13
|
|
12
14
|
# Number of processors seen by the OS and used for process scheduling. For performance
|