From: "Dan0042 (Daniel DeLorme) via ruby-core" Date: 2026-10-08T00:57:00+00:00 Subject: [ruby-core:127001] [Ruby Bug#22291] Instance variables should be forbidden on Ractor-shareable objects Issue #22291 has been updated by Dan0042 (Daniel DeLorme). > Classes/Modules are already special so that would be the exception we probably need to keep. I have often wondered, why not extend that special handling to all cases? ---------------------------------------- Bug #22291: Instance variables should be forbidden on Ractor-shareable objects https://bugs.ruby-lang.org/issues/22291#change-119394 * Author: jhawthorn (John Hawthorn) * Status: Closed * Backport: 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- Usually Ractor-shareable objects are frozen, but we have a number of objects which are shareable even though they aren't frozen (and likely will have more in the future from C extensions). * Classes/Modules (ignored in this issue, they have special ivar handling) * `Ractor` * `Ractor::Port` * Isolated procs/lambdas from `Ractor.shareable_proc` * `ENV` These are set shareable without the usual checks that all referenced objects are also shareable. This causes a potential issue, because these objects could have unshareable instance variables, breaking the Ractor invariant (potentially causing race conditions and segmentation faults). Currently, we attempt to avoid this by having a check on ivars read that forbids reading these from a non-main Ractor ``` R = Ractor.new {} R.instance_variable_set(:@iv, +"mutable") Ractor.new { R.instance_variable_get(:@iv) }.value #=> Ractor::IsolationError: can not access instance variables of shareable objects from non-main Ractors ``` This is detected by checking on ivar read for objects which are shareable but **not** frozen. However this isn't sound because most of these unshareable objects can be frozen, turning the check off. ```ruby R = Ractor.new {} R.instance_variable_set(:@iv, +"mutable") R.freeze Ractor.new { R.instance_variable_get(:@iv) }.value # => no error, created Ractor got access to an object it shouldn't ``` (weird quirk: `ENV#freeze` raises, but you can `Kernel.instance_method(:freeze).bind_call(ENV)` so it's still an issue) I propose that we fix this by forbidding instance variable writes to objects which are shareable (whether or not thy are frozen). This removes the need to check on read and maintains the Ractor invariant. ``` R = Ractor.new {} R.instance_variable_set(:@iv, 123) #=> Ractor::IsolationError: can not set instance variables of shareable Ractor objects Ractor.new { R.instance_variable_get(:@foo) # => always nil, because ivars are forbidden } ``` These objects behave essentially as though they're frozen, but only the IVs are frozen. This is an important issue to solve both for correctness, and because I want us to decide the semantics so that they can be implemented in ZJIT. Currently ZJIT won't compile ivar reads on multi-ractor mode because of this issue. (I will link a patch implementing this shortly) -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/