-
Notifications
You must be signed in to change notification settings - Fork 417
Description
Hello,
I would like to build a common synchronization layer in concurrent-ruby having following API:
def Concurrent.lock(object); end #reentrant
def Concurrent.try_lock(object); end
def Concurrent.unlock(object); end
def Concurrent.synchronize(object, &block); end
def Concurrent.wait(object, timeout = nil); end # as Java Object#wait
def Concurrent.signal(object); end # as Java Object#notify
def Concurrent.broadcast(object); end # as Java Object#notifyAllWhich would have different implementation based on Ruby interpreter.
I kindly ask @brixen @headius @hone @ko1 @yorickpeterse @zzak to help with finding the best options for the different implementations. This PR is intended to serve to discus the options and issues, I'll open PR with implementation later to discuss details based on what is figured out here.
Proposed implementations
MRI
Injecting Monitor to an object, something like:
require 'monitor'
INJECTION_BARRIER = Mutex.new
def synchronize(object)
get_mutex(object).synchronize { yield }
end
def lock(object)
get_mutex(object).enter
end
def unlock(object)
get_mutex(object).exit
end
def get_mutex(object)
object.instance_variable_get(:@__monitor__) or INJECTION_BARRIER.synchronize do
object.instance_variable_get(:@__monitor__) or
object.instance_variable_set(:@__monitor__, Monitor.new)
end
endSimilarly a ConditionVariable would be injected to support wait, signal, broadcast.
JRuby
Delegate to methods on JRuby module, see this PR jruby/jruby#2594.
It uses wait, notify, notifyAll methods on Java object to implement wait, signal, broadcast. synchronize runs a Block wrapped in synchronized Java keyword. lock, unlock, try_lock are using methods monitorEnter, monitorExit, tryMonitorEnter on sun.misc.Unsafe.
Rubinius
Implement lock, unlock, try_lock and synchronize by delegation to same methods on Rubinius module. wait, signal, broadcast would be supported by injecting ConditionalVariable into object's instance variable (when locked).