Skip to content

Commit 6dbfa92

Browse files
committed
Add ns_initialize which is always called inside synchronize block
1 parent b87f738 commit 6dbfa92

File tree

14 files changed

+72
-73
lines changed

14 files changed

+72
-73
lines changed

ext/com/concurrent_ruby/ext/SynchronizationLibrary.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ public JavaObject(Ruby runtime, RubyClass metaClass) {
4747
super(runtime, metaClass);
4848
}
4949

50-
@JRubyMethod
51-
public IRubyObject initialize(ThreadContext context) {
52-
return context.nil;
50+
@JRubyMethod(rest = true)
51+
public IRubyObject initialize(ThreadContext context, IRubyObject[] args, Block block) {
52+
synchronized (this) {
53+
return callMethod(context, "ns_initialize", args, block);
54+
}
5355
}
5456

5557
@JRubyMethod(name = "synchronize")
@@ -59,7 +61,7 @@ public IRubyObject rubySynchronize(ThreadContext context, Block block) {
5961
}
6062
}
6163

62-
@JRubyMethod(name = "ns_wait", optional = 1)
64+
@JRubyMethod(name = "ns_wait", optional = 1, visibility = 'private')
6365
public IRubyObject nsWait(ThreadContext context, IRubyObject[] args) {
6466
Ruby runtime = context.runtime;
6567
if (args.length > 1) {
@@ -91,13 +93,13 @@ public IRubyObject nsWait(ThreadContext context, IRubyObject[] args) {
9193
return this;
9294
}
9395

94-
@JRubyMethod(name = "ns_signal")
96+
@JRubyMethod(name = "ns_signal", visibility = 'private')
9597
public IRubyObject nsSignal(ThreadContext context) {
9698
notify();
9799
return this;
98100
}
99101

100-
@JRubyMethod(name = "ns_broadcast")
102+
@JRubyMethod(name = "ns_broadcast", visibility = 'private')
101103
public IRubyObject nsBroadcast(ThreadContext context) {
102104
notifyAll();
103105
return this;

lib/concurrent/actor/core.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class Core < Synchronization::Object
4747
# any logging system
4848
# @param [Proc] block for class instantiation
4949
def initialize(opts = {}, &block)
50-
super(&nil)
50+
super(&nil) # TODO use ns_initialize
5151
synchronize do
5252
@mailbox = Array.new
5353
@serialized_execution = SerializedExecution.new

lib/concurrent/at_exit.rb

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,6 @@ module Concurrent
88
class AtExitImplementation < Synchronization::Object
99
include Logging
1010

11-
def initialize(enabled = true)
12-
super()
13-
synchronize do
14-
@handlers = {}
15-
@enabled = enabled
16-
end
17-
end
18-
1911
# Add a handler to be run at `Kernel#at_exit`
2012
# @param [Object] handler_id optionally provide an id, if allready present, handler is replaced
2113
# @yield the handler
@@ -80,6 +72,11 @@ def run
8072

8173
private
8274

75+
def ns_initialize(enabled = true)
76+
@handlers = {}
77+
@enabled = enabled
78+
end
79+
8380
def runner
8481
run if synchronize { @enabled }
8582
end

lib/concurrent/atomic/count_down_latch.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,10 @@ class PureCountDownLatch < Synchronization::Object
2121
#
2222
# @raise [ArgumentError] if `count` is not an integer or is less than zero
2323
def initialize(count = 1)
24-
super()
2524
unless count.is_a?(Fixnum) && count >= 0
2625
raise ArgumentError.new('count must be in integer greater than or equal zero')
2726
end
28-
synchronize { @count = count }
27+
super(count)
2928
end
3029

3130
# @!macro [attach] count_down_latch_method_wait
@@ -58,6 +57,12 @@ def count_down
5857
def count
5958
synchronize { @count }
6059
end
60+
61+
private
62+
63+
def ns_initialize(count)
64+
@count = count
65+
end
6166
end
6267

6368
if Concurrent.on_jruby?

lib/concurrent/atomic/cyclic_barrier.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,10 @@ class CyclicBarrier < Synchronization::Object
1515
#
1616
# @raise [ArgumentError] if `parties` is not an integer or is less than zero
1717
def initialize(parties, &block)
18-
super(&nil)
1918
if !parties.is_a?(Fixnum) || parties < 1
2019
raise ArgumentError.new('count must be in integer greater than or equal zero')
2120
end
22-
synchronize do
23-
@parties = parties
24-
@action = block
25-
ns_next_generation
26-
end
21+
super(parties, &block)
2722
end
2823

2924
# @return [Fixnum] the number of threads needed to pass the barrier
@@ -101,6 +96,11 @@ def ns_next_generation
10196
@number_waiting = 0
10297
end
10398

99+
def ns_initialize(parties, &block)
100+
@parties = parties
101+
@action = block
102+
ns_next_generation
103+
end
104104

105105
end
106106
end

lib/concurrent/atomic/event.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ class Event < Synchronization::Object
1919
# `Event` will block.
2020
def initialize
2121
super
22-
synchronize do
23-
@set = false
24-
@iteration = 0
25-
end
2622
end
2723

2824
# Is the object in the set state?
@@ -83,5 +79,10 @@ def ns_set
8379
end
8480
true
8581
end
82+
83+
def ns_initialize
84+
@set = false
85+
@iteration = 0
86+
end
8687
end
8788
end

lib/concurrent/edge/future.rb

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ def future(default_executor = :io, &task)
3333

3434
alias_method :async, :future
3535

36-
# Constructs new Future which will be completed after block is evaluated on executor. Evaluation is delays until
37-
# requested by {Future#wait} method, {Future#value} and {Future#value!} methods are calling {Future#wait} internally.
36+
# Constructs new Future which will be completed after block is evaluated on executor. Evaluation is delayed until
37+
# requested by `#wait`, `#value`, `#value!`, etc.
3838
# @return [Delay]
3939
def delay(default_executor = :io, &task)
4040
Delay.new(default_executor).event.chain(&task)
@@ -84,12 +84,6 @@ def post_on(executor, *args, &job)
8484
class Event < Synchronization::Object
8585
extend FutureShortcuts
8686

87-
# @api private
88-
def initialize(promise, default_executor = :io)
89-
super()
90-
synchronize { ns_initialize(promise, default_executor) }
91-
end
92-
9387
# Is obligation completion still pending?
9488
# @return [Boolean]
9589
def pending?
@@ -624,12 +618,6 @@ def evaluate_to!(*args, &block)
624618

625619
# @abstract
626620
class AbstractPromise < Synchronization::Object
627-
# @api private
628-
def initialize(*args, &block)
629-
super(&nil)
630-
synchronize { ns_initialize(*args, &block) }
631-
end
632-
633621
def default_executor
634622
future.default_executor
635623
end

lib/concurrent/executor/serialized_execution.rb

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,6 @@ def call
1515
end
1616
end
1717

18-
def initialize
19-
super(&nil)
20-
synchronize do
21-
@being_executed = false
22-
@stash = []
23-
end
24-
end
25-
2618
# Submit a task to the executor for asynchronous processing.
2719
#
2820
# @param [Executor] executor to be used for this job
@@ -71,6 +63,11 @@ def posts(posts)
7163

7264
private
7365

66+
def ns_initialize
67+
@being_executed = false
68+
@stash = []
69+
end
70+
7471
def call_job(job)
7572
did_it_run = begin
7673
job.executor.post { work(job) }

lib/concurrent/synchronization.rb

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,21 @@
77

88
module Concurrent
99
module Synchronization
10-
class Object < case
11-
when Concurrent.on_jruby?
12-
JavaObject
10+
Implementation = case
11+
when Concurrent.on_jruby?
12+
JavaObject
13+
when Concurrent.on_cruby? && (RUBY_VERSION.split('.').map(&:to_i) <=> [1, 9, 3]) <= 0
14+
MonitorObject
15+
when Concurrent.on_cruby?
16+
MutexObject
17+
when Concurrent.on_rbx?
18+
RbxObject
19+
else
20+
MutexObject
21+
end
22+
private_constant :Implementation
1323

14-
when Concurrent.on_cruby? && (RUBY_VERSION.split('.').map(&:to_i) <=> [1, 9, 3]) <= 0
15-
MonitorObject
16-
17-
when Concurrent.on_cruby?
18-
MutexObject
19-
20-
when Concurrent.on_rbx?
21-
RbxObject
22-
23-
else
24-
MutexObject
25-
end
24+
class Object < Implementation
2625
end
2726
end
2827
end

lib/concurrent/synchronization/abstract_object.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ module Synchronization
88
# the classes using it. Use {Synchronization::Object} not this abstract class.
99
#
1010
# @note this object does not support usage together with
11-
# [Thread#wakeup](http://ruby-doc.org/core-2.2.0/Thread.html#method-i-wakeup)
12-
# and [Thread#raise](http://ruby-doc.org/core-2.2.0/Thread.html#method-i-raise).
11+
# [`Thread#wakeup`](http://ruby-doc.org/core-2.2.0/Thread.html#method-i-wakeup)
12+
# and [`Thread#raise`](http://ruby-doc.org/core-2.2.0/Thread.html#method-i-raise).
1313
# `Thread#sleep` and `Thread#wakeup` will work as expected but mixing `Synchronization::Object#wait` and
1414
# `Thread#wakeup` will not work on all platforms.
1515
#
@@ -29,8 +29,8 @@ module Synchronization
2929
class AbstractObject
3030

3131
# @abstract for helper ivar initialization if needed,
32-
# otherwise it can be left empty.
33-
def initialize
32+
# otherwise it can be left empty. It has to call ns_initialize.
33+
def initialize(*args, &block)
3434
raise NotImplementedError
3535
end
3636

@@ -52,6 +52,10 @@ def wait(timeout = nil)
5252
self
5353
end
5454

55+
# initialization of the object called inside synchronize block
56+
def ns_initialize(*args, &block)
57+
end
58+
5559
# Wait until condition is met or timeout passes,
5660
# protects against spurious wake-ups.
5761
# @param [Numeric, nil] timeout in seconds, `nil` means no timeout

0 commit comments

Comments
 (0)