Skip to content

Commit 6ceda0b

Browse files
authored
Merge pull request #727 from ruby-concurrency/pitr-ch/pool
Fix #717: Reenable java implementations, fix global IO executor on JRuby, bunch of other bug fixes
2 parents 3008823 + a026804 commit 6ceda0b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+526
-444
lines changed

Gemfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ group :development do
1010
gem 'rake-compiler-dock', '~> 0.6.0'
1111
gem 'gem-compiler', '~> 0.3.0'
1212
gem 'benchmark-ips', '~> 2.7'
13+
end
1314

14-
# documentation
15+
group :documentation do
1516
gem 'countloc', '~> 0.4.0', :platforms => :mri, :require => false
1617
# TODO (pitr-ch 04-May-2018): update to remove: [DEPRECATION] `last_comment` is deprecated. Please use `last_description` instead.
1718
gem 'yard', '~> 0.8.0', :require => false

concurrent-ruby-edge.gemspec

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
$:.push File.join(File.dirname(__FILE__), 'lib')
2-
$:.push File.join(File.dirname(__FILE__), 'support')
3-
4-
require 'concurrent/version'
5-
require 'file_map'
1+
require_relative 'lib/concurrent/version'
2+
require_relative 'support/file_map'
63

74
Gem::Specification.new do |s|
85
git_files = `git ls-files`.split("\n")

concurrent-ruby-ext.gemspec

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
$:.push File.join(File.dirname(__FILE__), 'lib')
2-
3-
require 'concurrent/version'
1+
require_relative 'lib/concurrent/version'
42

53
Gem::Specification.new do |s|
64
s.name = 'concurrent-ruby-ext'

concurrent-ruby.gemspec

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,26 @@
1-
$:.push File.join(File.dirname(__FILE__), 'lib')
2-
$:.push File.join(File.dirname(__FILE__), 'support')
3-
4-
require 'concurrent/version'
5-
require 'file_map'
1+
require_relative 'lib/concurrent/version'
2+
require_relative 'lib/concurrent/utility/engine'
3+
require_relative 'support/file_map'
64

75
Gem::Specification.new do |s|
8-
git_files = `git ls-files`.split("\n")
9-
106
s.name = 'concurrent-ruby'
117
s.version = Concurrent::VERSION
12-
s.platform = Gem::Platform::RUBY
8+
s.platform = Concurrent.on_jruby? ? Gem::Platform::JAVA : Gem::Platform::RUBY
139
s.authors = ["Jerry D'Antonio", 'Petr Chalupa', 'The Ruby Concurrency Team']
1410
s.email = '[email protected]'
1511
s.homepage = 'http://www.concurrent-ruby.com'
1612
s.summary = 'Modern concurrency tools for Ruby. Inspired by Erlang, Clojure, Scala, Haskell, F#, C#, Java, and classic concurrency patterns.'
1713
s.license = 'MIT'
1814
s.date = Time.now.strftime('%Y-%m-%d')
19-
s.files = FileMap::MAP.fetch(:core)
15+
s.files = [*FileMap::MAP.fetch(:core),
16+
*FileMap::MAP.fetch(:spec),
17+
*(Dir['lib/**/*.jar'] if Concurrent.on_jruby?)]
2018
s.extra_rdoc_files = Dir['README*', 'LICENSE*', 'CHANGELOG*']
2119
s.require_paths = ['lib']
22-
s.description = <<-EOF
23-
Modern concurrency tools including agents, futures, promises, thread pools, actors, supervisors, and more.
24-
Inspired by Erlang, Clojure, Go, JavaScript, actors, and classic concurrency patterns.
25-
EOF
26-
27-
if defined?(JRUBY_VERSION)
28-
s.files += Dir['lib/**/*.jar']
29-
s.platform = 'java'
30-
end
20+
s.description = <<-TXT.gsub(/^ +/, '')
21+
Modern concurrency tools including agents, futures, promises, thread pools, actors, supervisors, and more.
22+
Inspired by Erlang, Clojure, Go, JavaScript, actors, and classic concurrency patterns.
23+
TXT
3124

3225
s.required_ruby_version = '>= 1.9.3'
3326
end

ext/com/concurrent_ruby/ext/SynchronizationLibrary.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.jruby.RubyClass;
66
import org.jruby.RubyModule;
77
import org.jruby.RubyObject;
8+
import org.jruby.RubyThread;
89
import org.jruby.anno.JRubyClass;
910
import org.jruby.anno.JRubyMethod;
1011
import org.jruby.runtime.Block;
@@ -96,6 +97,14 @@ public void load(Ruby runtime, boolean wrap) throws IOException {
9697

9798
defineClass(runtime, synchronizationModule, "AbstractLockableObject", "JRubyLockableObject",
9899
JRubyLockableObject.class, JRUBY_LOCKABLE_OBJECT_ALLOCATOR);
100+
101+
defineClass(runtime, synchronizationModule, "Object", "JRuby",
102+
JRuby.class, new ObjectAllocator() {
103+
@Override
104+
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
105+
return new JRuby(runtime, klazz);
106+
}
107+
});
99108
}
100109

101110
private RubyClass defineClass(
@@ -267,4 +276,29 @@ public IRubyObject nsBroadcast(ThreadContext context) {
267276
return this;
268277
}
269278
}
279+
280+
@JRubyClass(name = "JRuby")
281+
public static class JRuby extends RubyObject {
282+
public JRuby(Ruby runtime, RubyClass metaClass) {
283+
super(runtime, metaClass);
284+
}
285+
286+
@JRubyMethod(name = "sleep_interruptibly", visibility = Visibility.PUBLIC, module = true)
287+
public static IRubyObject sleepInterruptibly(ThreadContext context, IRubyObject receiver, Block block) {
288+
try {
289+
return context.getThread().executeTask(context, block,
290+
new RubyThread.Task<Block, IRubyObject>() {
291+
public IRubyObject run(ThreadContext context, Block block1) throws InterruptedException {
292+
return block1.call(context);
293+
}
294+
295+
public void wakeup(RubyThread thread, Block block1) {
296+
thread.getNativeThread().interrupt();
297+
}
298+
});
299+
} catch (InterruptedException e) {
300+
throw context.runtime.newThreadError("interrupted in Concurrent::Synchronization::JRuby.sleep_interruptibly");
301+
}
302+
}
303+
}
270304
}

lib/concurrent/atomic/count_down_latch.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ module Concurrent
5555
# @!macro internal_implementation_note
5656
CountDownLatchImplementation = case
5757
when Concurrent.on_jruby?
58-
MutexCountDownLatch
58+
JavaCountDownLatch
5959
else
6060
MutexCountDownLatch
6161
end

lib/concurrent/atomic/java_count_down_latch.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,20 @@ class JavaCountDownLatch
99

1010
# @!macro count_down_latch_method_initialize
1111
def initialize(count = 1)
12-
unless count.is_a?(Fixnum) && count >= 0
13-
raise ArgumentError.new('count must be in integer greater than or equal zero')
14-
end
12+
Utility::NativeInteger.ensure_integer_and_bounds(count)
13+
Utility::NativeInteger.ensure_positive(count)
1514
@latch = java.util.concurrent.CountDownLatch.new(count)
1615
end
1716

1817
# @!macro count_down_latch_method_wait
1918
def wait(timeout = nil)
2019
if timeout.nil?
21-
@latch.await
20+
Synchronization::JRuby.sleep_interruptibly { @latch.await }
2221
true
2322
else
24-
@latch.await(1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS)
23+
Synchronization::JRuby.sleep_interruptibly do
24+
@latch.await(1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS)
25+
end
2526
end
2627
end
2728

lib/concurrent/collection/map/atomic_reference_map_backend.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,7 @@ def rebuild(table)
831831
# no lock needed (or available) if bin >= 0, because we're not popping values from locked_indexes until we've run through the whole table
832832
redo unless (bin >= 0 ? table.cas(i, nil, forwarder) : lock_and_clean_up_reverse_forwarders(table, old_table_size, new_table, i, forwarder))
833833
elsif Node.locked_hash?(node_hash = node.hash)
834-
locked_indexes ||= Array.new
834+
locked_indexes ||= ::Array.new
835835
if bin < 0 && locked_arr_idx > 0
836836
locked_arr_idx -= 1
837837
i, locked_indexes[locked_arr_idx] = locked_indexes[locked_arr_idx], i # swap with another bin

lib/concurrent/configuration.rb

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,8 @@ def self.new_fast_executor(opts = {})
175175
end
176176

177177
def self.new_io_executor(opts = {})
178-
ThreadPoolExecutor.new(
179-
min_threads: [2, Concurrent.processor_count].max,
180-
max_threads: ThreadPoolExecutor::DEFAULT_MAX_POOL_SIZE,
181-
# max_threads: 1000,
178+
CachedThreadPool.new(
182179
auto_terminate: opts.fetch(:auto_terminate, true),
183-
idletime: 60, # 1 minute
184-
max_queue: 0, # unlimited
185180
fallback_policy: :abort # shouldn't matter -- 0 max queue
186181
)
187182
end

lib/concurrent/edge/promises.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,8 +1797,8 @@ def process_on_blocker_resolution(future, index)
17971797

17981798
def on_resolvable(resolved_future, index)
17991799
all_fulfilled = true
1800-
values = Array.new(@Resolutions.size)
1801-
reasons = Array.new(@Resolutions.size)
1800+
values = ::Array.new(@Resolutions.size)
1801+
reasons = ::Array.new(@Resolutions.size)
18021802

18031803
@Resolutions.each_with_index do |internal_state, i|
18041804
fulfilled, values[i], reasons[i] = internal_state.result

0 commit comments

Comments
 (0)