-
-
Notifications
You must be signed in to change notification settings - Fork 925
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BUG: binding visibility for class_exec not thread safe? #4962
Comments
I believe you are correct, the visibility here is getting stepped on by multiple threads. The logic for This is a very unusual case, however. Because you're sharing a single global block across all threads, those threads also share state like We can fix this most simply by cloning the block and its binding when we do a |
Thanks for the quick response.
That was what I was thinking as well. However when I checked out the code,
seems a method setupBlock is trying to clone things; even the bindings. The
class_exec should execute on the cloned one.
I also tried dup diliberately in my code, however it did not work as there
might be references to original underlying stuff.
As ruby itself has GIL, that might be why it is working as expected.
Anyway I think it worths a fix as it is inconsistent behaviour.
Thanks
…On Thu, 11 Jan 2018 at 05:55, Charles Oliver Nutter < ***@***.***> wrote:
I believe you are correct, the visibility here is getting stepped on by
multiple threads.
The logic for class_exec forces the block's binding to public visibility,
restoring it on the way back out again. If another thread is also
evaluating the block, it will see the visibility change. That's what you
see here when the second method is defined private.
This is a very unusual case, however. Because you're sharing a single
global block across all threads, those threads also share state like $~
value.
We can fix this most simply by cloning the block and its binding when we
do a class_exec but that will prevent sharing anything, and some of the
sharing is intentional.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#4962 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAiSM6ZLcMFr79RGqUaAZJSYI3Awxkp8ks5tJQeQgaJpZM4RYsN9>
.
|
It is possible the GIL has some effect, but after looking at CRuby's code a bit I see it does appear to create a new "cref" for the exec. I'll play with our duping and see if I can figure out the equivalent logic. |
I've pushed branch clone_more_block_for_exec with some extra logic to clone the block and the frame associated with it (which is where the visibility is stored). We'll see how it looks in CI. |
So it looks like CI was mostly happy. Does this mean the patch can be pushed forward? |
@wezm Thanks for pinging! Yes, I think we can merge this in now for 9.2. |
Environment
Provide at least:
jruby -v
) and command line (flags, JRUBY_OPTS, etc)uname -a
)Expected Behavior
class_exec
should be thread_safeclass_exec
should always use visibility:public
Actual Behavior
NoMethodError
with a message showing calling private method, see belowThe text was updated successfully, but these errors were encountered: