Skip to content

Commit a3e9b02

Browse files
committed
[GR-28354] Workaround for no "before CacheStore hook" yet
1 parent 98c4d6e commit a3e9b02

File tree

1 file changed

+33
-8
lines changed

1 file changed

+33
-8
lines changed

src/main/java/org/truffleruby/RubyLanguage.java

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ private RubyThread getOrCreateForeignThread(RubyContext context, Thread thread)
231231

232232
@CompilationFinal public boolean singleContext = true;
233233
@CompilationFinal public Optional<RubyContext> contextIfSingleContext;
234+
private int numberOfContexts = 0;
234235

235236
public final CyclicAssumption traceFuncUnusedAssumption = new CyclicAssumption("set_trace_func is not used");
236237

@@ -248,7 +249,7 @@ private RubyThread getOrCreateForeignThread(RubyContext context, Thread thread)
248249

249250
// GR-44025: We store the cleanerThread explicitly here to make it a clear image building failure if it would still be set.
250251
public Thread cleanerThread = null;
251-
@CompilationFinal public Cleaner cleaner = newCleaner();
252+
@CompilationFinal public Cleaner cleaner = null;
252253

253254
public volatile ValueWrapperManager.HandleBlockWeakReference[] handleBlockSharedMap = new ValueWrapperManager.HandleBlockWeakReference[0];
254255
public final ValueWrapperManager.HandleBlockAllocator handleBlockAllocator = new ValueWrapperManager.HandleBlockAllocator();
@@ -424,6 +425,9 @@ public RubyContext createContext(Env env) {
424425
Metrics.initializeOption();
425426

426427
synchronized (this) {
428+
numberOfContexts++;
429+
setupCleaner();
430+
427431
if (this.options == null) { // First context
428432
this.allocationReporter = env.lookup(AllocationReporter.class);
429433
this.options = new LanguageOptions(env, env.getOptions(), singleContext);
@@ -465,9 +469,10 @@ protected void initializeContext(RubyContext context) {
465469
context.initialize();
466470

467471
if (context.isPreInitializing()) {
468-
setRubyHome(context.getEnv(), null);
469-
this.cleanerThread = null;
470-
this.cleaner = null;
472+
synchronized (this) {
473+
setRubyHome(context.getEnv(), null);
474+
resetCleaner();
475+
}
471476
}
472477
Metrics.printTime("after-initialize-context");
473478
} catch (Throwable e) {
@@ -498,8 +503,10 @@ protected boolean patchContext(RubyContext context, Env newEnv) {
498503
return false;
499504
}
500505

501-
setRubyHome(newEnv, findRubyHome());
502-
this.cleaner = newCleaner();
506+
synchronized (this) {
507+
setRubyHome(newEnv, findRubyHome());
508+
setupCleaner();
509+
}
503510

504511
boolean patched = context.patchContext(newEnv);
505512
Metrics.printTime("after-patch-context");
@@ -520,6 +527,14 @@ protected void disposeContext(RubyContext context) {
520527
if (options.COVERAGE_GLOBAL) {
521528
coverageManager.print(this, System.out);
522529
}
530+
531+
synchronized (this) {
532+
// GR-28354: Workaround for no "before CacheStore hook"
533+
numberOfContexts--;
534+
if (numberOfContexts == 0 && !singleContext) {
535+
resetCleaner();
536+
}
537+
}
523538
}
524539

525540
public static RubyContext getCurrentContext() {
@@ -659,8 +674,17 @@ protected Object getScope(RubyContext context) {
659674
return context.getTopScopeObject();
660675
}
661676

662-
private Cleaner newCleaner() {
663-
return Cleaner.create(runnable -> this.cleanerThread = new Thread(runnable, "Ruby-Cleaner"));
677+
private void setupCleaner() {
678+
assert Thread.holdsLock(this);
679+
if (cleaner == null) {
680+
cleaner = Cleaner.create(runnable -> this.cleanerThread = new Thread(runnable, "Ruby-Cleaner"));
681+
}
682+
}
683+
684+
private void resetCleaner() {
685+
assert Thread.holdsLock(this);
686+
cleanerThread = null;
687+
cleaner = null;
664688
}
665689

666690
public String getRubyHome() {
@@ -681,6 +705,7 @@ public String getPathRelativeToHome(String path) {
681705
}
682706

683707
private void setRubyHome(Env env, String home) {
708+
assert Thread.holdsLock(this);
684709
rubyHome = home;
685710
setRubyHomeTruffleFile(env, home);
686711
}

0 commit comments

Comments
 (0)