You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
require'monitor'classExampleincludeMonitorMixindefinitialize(*array)mon_initialize@array=arrayenddefmodifysynchronizedo@array.map!{ |e| e + 1}endenddefto_asynchronize{@array.dup}endprivatedefinitialize_copy(other)# Initialize a new mutex in the copymon_initialize# Add copied state while ensuring it can be safely added here in any casesynchronizedo@array=other.to_aendendend
When initializing an object and subsequently dup'ing it, TriffleRuby unexpectedly raises a deadlock:
example=Example.new(1,2,3)copy=example.dup# ThreadError: deadlock; recursive locking# from /Users/User/.rubies/truffleruby-1.0.0-rc6/lib/mri/monitor.rb:187:in `lock'# from /Users/User/.rubies/truffleruby-1.0.0-rc6/lib/mri/monitor.rb:187:in `mon_enter'# from /Users/User/.rubies/truffleruby-1.0.0-rc6/lib/mri/monitor.rb:212:in `mon_synchronize'# from (irb):18:in `to_a'# from (irb):29:in `block in initialize_copy'# from /Users/User/.rubies/truffleruby-1.0.0-rc6/lib/mri/monitor.rb:214:in `mon_synchronize'# from (irb):28:in `initialize_copy'# from (irb):34:in `initialize_dup'# from (irb):34:in `dup'# from (irb):34# from /Users/User/.rubies/truffleruby-1.0.0-rc6/bin/irb:29:in `<main>'
In TruffleRuby, the mon_initialize call in initialize_copy is effectively a no-op following d675e82#diff-58dfe1911468f7ccd5bf9bed448b7b48. When copying a monitor, I find it rather surprising that the copy silently uses the original mutex instead of actually initializing a new one.
The example might be a bit contrived, but the issue / bug would still manifest itself later given that the two objects still share the same mutex and can thus not operate concurrently.
Thus, I request that this TruffleRuby specific modification of the MonitorMixin is dropped from TruffleRuby to restore MRI-compatible behavior.
The text was updated successfully, but these errors were encountered:
Thank you for the report.
FWIW, my original commit tried to prevent it more directly: 1adf384, but that made Rails tests fail :(
Anyway, we did not expect mon_initialize to be called from initialize_copy, so we will fix this case.
Obviously, this bug is not intended, no need to "request" changes 😉
There are probably a lot of other cases too where mon_initialize might be called again with the expectation that it always sets a new mutex, e.g. when using "creative" ways to build objects.
Isn't it possible to completely retain MRI's behavior and always initialize the monitor (again) when mon_initialize is called? I think it's the caller's responsibility to only do this when necessary and intended.
Consider the following example class:
When initializing an object and subsequently
dup
'ing it, TriffleRuby unexpectedly raises a deadlock:In TruffleRuby, the
mon_initialize
call ininitialize_copy
is effectively a no-op following d675e82#diff-58dfe1911468f7ccd5bf9bed448b7b48. When copying a monitor, I find it rather surprising that the copy silently uses the original mutex instead of actually initializing a new one.The example might be a bit contrived, but the issue / bug would still manifest itself later given that the two objects still share the same mutex and can thus not operate concurrently.
Thus, I request that this TruffleRuby specific modification of the
MonitorMixin
is dropped from TruffleRuby to restore MRI-compatible behavior.The text was updated successfully, but these errors were encountered: