Skip to content

Commit

Permalink
Synchronize state in AbstractVariable and Argv
Browse files Browse the repository at this point in the history
These fields are changed together but without any synchronization
or atomicity. Simplest fix for now is to synchronize the methods
and mark them as volatile.

Fixes jruby#8178
  • Loading branch information
headius committed May 9, 2024
1 parent d7358ea commit 9af8a68
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ abstract class AbstractVariable implements BiVariable {
*/
protected final IRubyObject receiver;
protected final String name;
protected Object javaObject = null;
protected Class javaType = null;
protected IRubyObject rubyObject = null;
protected boolean fromRuby;
protected volatile Object javaObject;
protected volatile Class javaType;
protected volatile IRubyObject rubyObject;
protected volatile boolean fromRuby;

/**
* Constructor used when this variable is originaed from Java.
Expand Down Expand Up @@ -94,7 +94,7 @@ static RubyObject getTopSelf(final IRubyObject receiver) {
return (RubyObject) receiver.getRuntime().getTopSelf();
}

protected void updateByJavaObject(final Ruby runtime, Object... values) {
protected synchronized void updateByJavaObject(final Ruby runtime, Object... values) {
assert values != null;
javaObject = values[0];
if (javaObject == null) {
Expand All @@ -108,7 +108,7 @@ protected void updateByJavaObject(final Ruby runtime, Object... values) {
fromRuby = false;
}

protected void updateRubyObject(final IRubyObject rubyObject) {
protected synchronized void updateRubyObject(final IRubyObject rubyObject) {
if ( rubyObject == null ) return;
this.rubyObject = rubyObject;
this.javaType = null;
Expand All @@ -134,7 +134,7 @@ public String getName() {
return name;
}

public Object getJavaObject() {
public synchronized Object getJavaObject() {
if (rubyObject == null) return javaObject;

if (javaType != null) { // Java originated variables
Expand Down
8 changes: 4 additions & 4 deletions core/src/main/java/org/jruby/embed/variable/Argv.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public static boolean isValidName(Object name) {
* invoked during EvalUnit#run() is executed.
*/
@Override
public void inject() {
public synchronized void inject() {
final Ruby runtime = getRuntime();

final RubyArray argv = RubyArray.newArray(runtime);
Expand All @@ -141,7 +141,7 @@ else if ( javaObject instanceof String[] ) {
* this variable in top self.
*/
@Override
public void remove() {
public synchronized void remove() {
this.javaObject = new ArrayList();
inject();
}
Expand Down Expand Up @@ -173,7 +173,7 @@ private static void updateARGV(final IRubyObject receiver, final BiVariableMap v
}

// ARGV appears to require special treatment, leaving javaType intact
protected void updateRubyObject(final IRubyObject rubyObject) {
protected synchronized void updateRubyObject(final IRubyObject rubyObject) {
if ( rubyObject == null ) return;
this.rubyObject = rubyObject;
}
Expand All @@ -193,7 +193,7 @@ public static void retrieveByKey(RubyObject receiver, BiVariableMap vars, String

@Override
@SuppressWarnings("unchecked")
public Object getJavaObject() {
public synchronized Object getJavaObject() {
if ( rubyObject == null || ! fromRuby ) return javaObject;

final RubyArray ary = (RubyArray) rubyObject;
Expand Down

0 comments on commit 9af8a68

Please sign in to comment.