Jruby: Global variables read stale values

Created on 25 Sep 2017  路  4Comments  路  Source: jruby/jruby

Environment

  • JRuby 9.1.13.0 and before
  • Linux

Global variable reads should behave as if they are volatile, so they always get the latest value.

However, it seems the invokedynamic implementation is not thread-safe or make some of the reads just get stale values, and never see the new value.

See bug_jruby_globals.rb to reproduce.

It accepts a number of threads as an argument.
Locally, the script never terminates with 4 threads, it does 1 to ~5 iterations and gets stuck.

Passing -Xinvokedynamic.global.maxfail=0 solves the problem so it seems related to invokedynamic globals. Running on MRI or TruffleRuby (which also treat global variables as constants until they are changed) also works fine.

concurrency invokedynamic

Most helpful comment

Nice find, thanks. I feel like the way our globals are structured needs a reboot (the current way is WAY over-abstracted) but I'll have a look at fixing this in place for now.

All 4 comments

There seems to be other thread safety issues in the implementation of globals:

Nice find, thanks. I feel like the way our globals are structured needs a reboot (the current way is WAY over-abstracted) but I'll have a look at fixing this in place for now.

A fix is in for 9.1.14 that basically just disables the caching like @eregon did. I am resolving this as fixed and will file a separate bug for the many race conditions we need to deal with.

I've updated the code in #5536 to gracefully fall back on a volatile field when a global is modified more than MAXFAIL times. That PR appears to allow this script to run safely with any number of threads all contending the globals (resolving #4808).

Was this page helpful?
0 / 5 - 0 ratings