@@ -102,10 +102,15 @@ public RubyFiber createFiber(RubyLanguage language, RubyContext context, RubyThr
102
102
}
103
103
104
104
public void initialize (RubyFiber fiber , RubyProc block , Node currentNode ) {
105
+ final TruffleContext truffleContext = context .getEnv ().getContext ();
106
+
105
107
ThreadManager .FIBER_BEING_SPAWNED .set (fiber );
106
108
try {
107
- context .getThreadManager ().spawnFiber (fiber , () -> fiberMain (context , fiber , block , currentNode ));
108
- waitForInitialization (context , fiber , currentNode );
109
+ context .getThreadManager ().leaveAndEnter (truffleContext , currentNode , () -> {
110
+ context .getThreadManager ().spawnFiber (fiber , () -> fiberMain (context , fiber , block , currentNode ));
111
+ waitForInitialization (context , fiber , currentNode );
112
+ return BlockingAction .SUCCESS ;
113
+ }, context .getThreadManager ().isRubyManagedThread (Thread .currentThread ()));
109
114
} finally {
110
115
ThreadManager .FIBER_BEING_SPAWNED .remove ();
111
116
}
@@ -115,10 +120,16 @@ public void initialize(RubyFiber fiber, RubyProc block, Node currentNode) {
115
120
public static void waitForInitialization (RubyContext context , RubyFiber fiber , Node currentNode ) {
116
121
final CountDownLatch initializedLatch = fiber .initializedLatch ;
117
122
118
- context . getThreadManager (). runUntilResultKeepStatus ( currentNode , () -> {
123
+ final BlockingAction < Boolean > blockingAction = () -> {
119
124
initializedLatch .await ();
120
125
return BlockingAction .SUCCESS ;
121
- });
126
+ };
127
+
128
+ if (context .getEnv ().getContext ().isEntered ()) {
129
+ context .getThreadManager ().runUntilResultKeepStatus (currentNode , blockingAction );
130
+ } else {
131
+ ThreadManager .retryWhileInterrupted (blockingAction );
132
+ }
122
133
123
134
final Throwable uncaughtException = fiber .uncaughtException ;
124
135
if (uncaughtException != null ) {
@@ -141,9 +152,14 @@ private void fiberMain(RubyContext context, RubyFiber fiber, RubyProc block, Nod
141
152
final TruffleContext truffleContext = context .getEnv ().getContext ();
142
153
assert !truffleContext .isEntered ();
143
154
144
- final FiberMessage message = waitMessage (fiber );
145
- final Object prev = truffleContext .enter (currentNode );
155
+ final Object prev = truffleContext .enter (currentNode ); // enter and leave now to workaround GR-29773
146
156
context .getSafepointManager ().enterThread (); // not done in start() above because the context was not entered
157
+ final FiberMessage message = context .getThreadManager ().leaveAndEnter (truffleContext , currentNode , () -> {
158
+ // fully initialized
159
+ fiber .initializedLatch .countDown ();
160
+ return waitMessage (fiber );
161
+ }, true );
162
+
147
163
try {
148
164
final Object result ;
149
165
try {
@@ -277,9 +293,6 @@ public void start(RubyFiber fiber, Thread javaThread, boolean entered) {
277
293
if (threadManager .isRubyManagedThread (javaThread ) && Thread .currentThread () == javaThread && entered ) {
278
294
context .getSafepointManager ().enterThread ();
279
295
}
280
-
281
- // fully initialized
282
- fiber .initializedLatch .countDown ();
283
296
}
284
297
285
298
public void cleanup (RubyFiber fiber , Thread javaThread , boolean entered ) {
0 commit comments