Skip to content

Commit

Permalink
Revert previous changes for TruffleRuby
Browse files Browse the repository at this point in the history
* use same approach as for JRuby
* use non public TruffleRuby API for simplicity
  • Loading branch information
pitr-ch committed Jul 1, 2018
1 parent 04db895 commit bdcd61f
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 36 deletions.
25 changes: 20 additions & 5 deletions lib/concurrent/array.rb
Expand Up @@ -2,7 +2,8 @@
require 'concurrent/thread_safe/util'

module Concurrent
if Concurrent.on_cruby?
case
when Concurrent.on_cruby?

# Because MRI never runs code in parallel, the existing
# non-thread-safe structures should usually work fine.
Expand All @@ -21,26 +22,40 @@ module Concurrent
# may be lost. Use `#concat` instead.
#
# @see http://ruby-doc.org/core-2.2.0/Array.html Ruby standard library `Array`
class Array < ::Array;
class Array < ::Array
end

elsif Concurrent.on_jruby?
when Concurrent.on_jruby?
require 'jruby/synchronized'

# @!macro concurrent_array
class Array < ::Array
include JRuby::Synchronized
end

elsif Concurrent.on_rbx? || Concurrent.on_truffleruby?
when Concurrent.on_rbx?
require 'monitor'
require 'concurrent/thread_safe/util/array_hash_rbx'
require 'concurrent/thread_safe/util/data_structures'

# @!macro concurrent_array
class Array < ::Array
end

ThreadSafe::Util.make_synchronized_on_rbx Concurrent::Array

when Concurrent.on_truffleruby?
require 'concurrent/thread_safe/util/data_structures'

# @!macro concurrent_array
class Array < ::Array
end

ThreadSafe::Util.make_synchronized_on_truffleruby Concurrent::Array

else
warn 'Possibly unsupported Ruby implementation'
class Array < ::Array
end
end
end

27 changes: 22 additions & 5 deletions lib/concurrent/hash.rb
Expand Up @@ -2,7 +2,8 @@
require 'concurrent/thread_safe/util'

module Concurrent
if Concurrent.on_cruby?
case
when Concurrent.on_cruby?

# @!macro [attach] concurrent_hash
#
Expand All @@ -12,25 +13,41 @@ module Concurrent
# which takes the lock repeatedly when reading an item.
#
# @see http://ruby-doc.org/core-2.2.0/Hash.html Ruby standard library `Hash`
class Hash < ::Hash;
class Hash < ::Hash
end

elsif Concurrent.on_jruby?
when Concurrent.on_jruby?
require 'jruby/synchronized'

# @!macro concurrent_hash
class Hash < ::Hash
include JRuby::Synchronized
end

elsif Concurrent.on_rbx? || Concurrent.on_truffleruby?
when Concurrent.on_rbx?
require 'monitor'
require 'concurrent/thread_safe/util/array_hash_rbx'
require 'concurrent/thread_safe/util/data_structures'

# @!macro concurrent_hash
class Hash < ::Hash
end

ThreadSafe::Util.make_synchronized_on_rbx Concurrent::Hash

when Concurrent.on_truffleruby?
require 'concurrent/thread_safe/util/data_structures'

# @!macro concurrent_hash
class Hash < ::Hash
end

ThreadSafe::Util.make_synchronized_on_truffleruby Concurrent::Hash

else
warn 'Possibly unsupported Ruby implementation'
class Hash < ::Hash
end

end
end

25 changes: 20 additions & 5 deletions lib/concurrent/set.rb
Expand Up @@ -3,7 +3,8 @@
require 'set'

module Concurrent
if Concurrent.on_cruby?
case
when Concurrent.on_cruby?

# Because MRI never runs code in parallel, the existing
# non-thread-safe structures should usually work fine.
Expand All @@ -25,23 +26,37 @@ module Concurrent
class Set < ::Set;
end

elsif Concurrent.on_jruby?
when Concurrent.on_jruby?
require 'jruby/synchronized'

# @!macro concurrent_Set
class Set < ::Set
include JRuby::Synchronized
end

elsif Concurrent.on_rbx? || Concurrent.on_truffleruby?
when Concurrent.on_rbx?
require 'monitor'
require 'concurrent/thread_safe/util/array_hash_rbx'
require 'concurrent/thread_safe/util/data_structures'

# @!macro concurrent_Set
class Set < ::Set
end

ThreadSafe::Util.make_synchronized_on_rbx Set
ThreadSafe::Util.make_synchronized_on_rbx Concurrent::Set

when Concurrent.on_truffleruby?
require 'concurrent/thread_safe/util/data_structures'

# @!macro concurrent_array
class Set < ::Set
end

ThreadSafe::Util.make_synchronized_on_truffleruby Concurrent::Set

else
warn 'Possibly unsupported Ruby implementation'
class Set < ::Set
end
end
end

Expand Up @@ -6,23 +6,13 @@ module Util
def self.make_synchronized_on_rbx(klass)
klass.class_eval do
private

def _mon_initialize
@_monitor = Monitor.new unless @_monitor # avoid double initialisation
end

def initialize(*args)
_mon_initialize
super
end

def self.allocate
obj = super
obj.send(:_mon_initialize)
obj
end

def self.[](*args)
obj = super
def self.new(*args)
obj = super(*args)
obj.send(:_mon_initialize)
obj
end
Expand All @@ -42,18 +32,24 @@ def #{method}(*args)
klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{method}(*args)
monitor = @_monitor
unless monitor
raise("BUG: Internal monitor was not properly initialized. Please report this to the "\
"concurrent-ruby developers.")
end
monitor or raise("BUG: Internal monitor was not properly initialized. Please report this to the concurrent-ruby developers.")
monitor.synchronize { super }
end
RUBY
end
end
end

def self.make_synchronized_on_truffleruby(klass)
klass.superclass.instance_methods(false).each do |method|
klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{method}(*args, &block)
# TODO (pitr-ch 01-Jul-2018): don't use internal TruffleRuby APIs
Truffle::System.synchronized(self) { super(*args, &block) }
end
RUBY
end
end
end
end
end
4 changes: 2 additions & 2 deletions spec/concurrent/array_spec.rb
Expand Up @@ -68,7 +68,7 @@ module Concurrent
context 'concurrency' do
it do
(1..Concurrent::ThreadSafe::Test::THREADS).map do |i|
in_thread do
in_thread(ary) do |ary|
1000.times do
ary << i
ary.each { |x| x * 2 }
Expand All @@ -82,7 +82,7 @@ module Concurrent
end

describe '#slice' do
# This is mostly relevant on Rubinius and Truffle
# This is mostly relevant on Rubinius and TruffleRuby
it 'correctly initializes the monitor' do
ary.concat([0, 1, 2, 3, 4, 5, 6, 7, 8])

Expand Down

0 comments on commit bdcd61f

Please sign in to comment.