Skip to content

Commit

Permalink
Fix a race in indy global var caching
Browse files Browse the repository at this point in the history
The logic here acquires the Invalidator from the variable and uses
that to guard the cached value. However, if this is a SwitchPoint
invalidator (assumed by the code) then it replaces the SwitchPoint
with a new one after invalidation. If we do not grab the actual
SwitchPoint before the value, we may end up associating the
current value with a newer SwitchPoint and never see the
subsequent update.

This is likely the main cause of intermittent global variable
failures with indy global caching turned on.
  • Loading branch information
headius committed Nov 3, 2023
1 parent 0a69e63 commit 929fe3c
Showing 1 changed file with 2 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,15 @@ public IRubyObject getGlobalFallback(ThreadContext context) throws Throwable {
return (IRubyObject)uncached.invokeWithArguments(context);
}

Invalidator invalidator = variable.getInvalidator();
SwitchPoint invalidator = (SwitchPoint) variable.getInvalidator().getData();
IRubyObject value = variable.getAccessor().getValue();

MethodHandle target = constant(IRubyObject.class, value);
target = dropArguments(target, 0, ThreadContext.class);
MethodHandle fallback = lookup().findVirtual(GlobalSite.class, "getGlobalFallback", methodType(IRubyObject.class, ThreadContext.class));
fallback = fallback.bindTo(this);

target = ((SwitchPoint)invalidator.getData()).guardWithTest(target, fallback);
target = invalidator.guardWithTest(target, fallback);

setTarget(target);

Expand Down

0 comments on commit 929fe3c

Please sign in to comment.