Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Thread safety problem in class_exec #2221

ryoqun opened this Issue · 2 comments

1 participant


Well, this is REALLY convoluted code, but we have a thread-safety problem in class_exec and other eval-like methods. I've prepared a test code for it.

Run like this:

$ PARALLEL=1 ./bin/rbx -X19 ./parallel-class-exec.rb
rubinius 2.0.0.rc1 (1.8.7 313ba5c7 yyyy-mm-dd) [x86_64-unknown-linux-gnu]
An exception occurred running /tmp/parallel-class-exec.rb
    undefined method `get_value' on an instance of M::B. (NoMethodError)

There should be no NoMethodErrors.

The problem is that scope of blocks passed to class_exec incorrectly mutates when running with multi-threads. In the test code, while undef-ing get_value and re-def-ining get_value (see below for the conceptual code), sometimes the current scope is switched from M::A to M::B or vice versa, when class_exec-ing on separate classes, not on a single shared class. And odd things occur:

class_exec { undef :get_value }
class_exec do
  def get_value

Note that this is not an usual thread-unsafe problem which users must be aware of. This code never changes the shared runtime state in unordered way. So, this should not happen.

This code just sequentially do class_exec on M::A and M::B in completely independent threads. The twist is they are using the same block.

I'm planning to fix this. The culpit is the bytecode instruction create_block is carelessly changing CompiledCode's instance variable @scope. So, because CompiledCode blocks are shared between across multiple threads in this code, Rubinius shouldn't change its state carelessly. In other words, this is happening because CompiledCode isn't thread-safe. This smells a bit. And this bug is just a test case for it, there may be other potential problems.

Also, I think this hinders parallel performance, because multiple threads are chaning the value of the same address. Nowadays, invalidating CPU cache is extremely costs. I'll check it when this work is finished. Stay tuned!


Well, my test code is actually not thread-safe itself. I've updated it.


Also, this exposed jit issue.. investigating..

@dbussink dbussink closed this issue from a commit
@dbussink dbussink Fix thread safety issue with modifying constant scope for code
Modifying compiled code objects at runtime results in race conditions if
the code is executed under different contexts in multiple threads.

This changes it to always use the constant scope from the call frame and
set this up properly for all the cases. Also the JIT needs to setup
these frames properly.

Also ensures that the JIT also checks the constant scope when validating
an inlined constant.

Fixes #2221
@dbussink dbussink closed this in 075d79f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.