65
65
import static com .oracle .graal .python .nodes .StringLiterals .T_WARNINGS ;
66
66
import static com .oracle .graal .python .nodes .truffle .TruffleStringMigrationHelpers .isJavaString ;
67
67
import static com .oracle .graal .python .util .PythonUtils .TS_ENCODING ;
68
- import static com .oracle .graal .python .util .PythonUtils .initUnsafe ;
69
68
import static com .oracle .graal .python .util .PythonUtils .toTruffleStringUncached ;
70
69
import static com .oracle .graal .python .util .PythonUtils .tsLiteral ;
71
70
@@ -352,12 +351,6 @@ public static final class PythonThreadState {
352
351
*/
353
352
Object nativeThreadLocalVarPointer ;
354
353
355
- /**
356
- * Raw pointer to {@link #nativeThreadLocalVarPointer} if available, so that we can clean up
357
- * during thread disposal.
358
- */
359
- long nativeThreadLocalVarRawPointer ;
360
-
361
354
/* The global tracing function, set by sys.settrace and returned by sys.gettrace. */
362
355
Object traceFun ;
363
356
@@ -537,7 +530,7 @@ public void setContextVarsContext(PContextVarsContext contextVarsContext) {
537
530
this .contextVarsContext = contextVarsContext ;
538
531
}
539
532
540
- public void dispose (PythonContext context ) {
533
+ public void dispose (PythonContext context , boolean canRunGuestCode ) {
541
534
// This method may be called twice on the same object.
542
535
543
536
/*
@@ -558,14 +551,11 @@ public void dispose(PythonContext context) {
558
551
}
559
552
/*
560
553
* Write 'NULL' to the native thread-local variable used to store the PyThreadState
561
- * struct such that it cannot accidentally be reused. We can invoke LLVM only if we are
562
- * not shutting down the thread.
554
+ * struct such that it cannot accidentally be reused. Since this is done as a
555
+ * precaution, we just skip this if we cannot run guest code, because it may invoke
556
+ * LLVM.
563
557
*/
564
- if (nativeThreadLocalVarRawPointer != 0 && context .env .isNativeAccessAllowed ()) {
565
- context .getUnsafe ().putAddress (nativeThreadLocalVarRawPointer , 0 );
566
- nativeThreadLocalVarRawPointer = 0 ;
567
- nativeThreadLocalVarPointer = null ;
568
- } else if (nativeThreadLocalVarPointer != null && !isShuttingDown ()) {
558
+ if (nativeThreadLocalVarPointer != null && canRunGuestCode ) {
569
559
CStructAccess .WritePointerNode .writeUncached (nativeThreadLocalVarPointer , 0 , context .getNativeNull ());
570
560
nativeThreadLocalVarPointer = null ;
571
561
}
@@ -636,22 +626,10 @@ public void setAsyncgenFirstIter(Object asyncgenFirstIter) {
636
626
this .asyncgenFirstIter = asyncgenFirstIter ;
637
627
}
638
628
639
- public void resetNativeThreadLocalVarPointer () {
640
- nativeThreadLocalVarRawPointer = 0 ;
641
- nativeThreadLocalVarPointer = null ;
642
- }
643
-
644
- public void setNativeThreadLocalVarPointer (InteropLibrary interop , Object ptr ) {
629
+ public void setNativeThreadLocalVarPointer (Object ptr ) {
645
630
// either unset or same
646
631
assert nativeThreadLocalVarPointer == null || nativeThreadLocalVarPointer == ptr ||
647
632
InteropLibrary .getUncached ().isIdentical (nativeThreadLocalVarPointer , ptr , InteropLibrary .getUncached ());
648
- if (interop .isPointer (ptr )) {
649
- try {
650
- this .nativeThreadLocalVarRawPointer = interop .asPointer (ptr );
651
- } catch (UnsupportedMessageException e ) {
652
- throw CompilerDirectives .shouldNotReachHere (e );
653
- }
654
- }
655
633
this .nativeThreadLocalVarPointer = ptr ;
656
634
}
657
635
}
@@ -2191,7 +2169,7 @@ public void runShutdownHooks() {
2191
2169
@ TruffleBoundary
2192
2170
private void disposeThreadStates () {
2193
2171
for (PythonThreadState ts : threadStateMapping .values ()) {
2194
- ts .dispose (this );
2172
+ ts .dispose (this , true );
2195
2173
}
2196
2174
threadStateMapping .clear ();
2197
2175
}
@@ -2270,7 +2248,7 @@ private void joinPythonThreads() {
2270
2248
// they are still running some GraalPython code, if they are embedder threads
2271
2249
// that are not running GraalPython code anymore, they will just never receive
2272
2250
// PythonThreadKillException and continue as if nothing happened.
2273
- disposeThread (thread );
2251
+ disposeThread (thread , true );
2274
2252
boolean isOurThread = runViaLauncher || thread .getThreadGroup () == threadGroup ;
2275
2253
// Do not try so hard when running in embedded mode and the thread may not be
2276
2254
// running any GraalPython code anymore
@@ -2364,6 +2342,11 @@ public void killSystemThread(Thread thread) {
2364
2342
env .submitThreadLocal (new Thread []{thread }, new ThreadLocalAction (true , false ) {
2365
2343
@ Override
2366
2344
protected void perform (ThreadLocalAction .Access access ) {
2345
+ // just in case the thread holds GIL
2346
+ PythonContext ctx = PythonContext .get (null );
2347
+ if (ctx .ownsGil ()) {
2348
+ ctx .releaseGil ();
2349
+ }
2367
2350
throw new PythonThreadKillException ();
2368
2351
}
2369
2352
});
@@ -2630,7 +2613,7 @@ public synchronized void attachThread(Thread thread, ContextThreadLocal<PythonTh
2630
2613
threadStateMapping .put (thread , threadState .get (thread ));
2631
2614
}
2632
2615
2633
- public synchronized void disposeThread (Thread thread ) {
2616
+ public synchronized void disposeThread (Thread thread , boolean canRunGuestCode ) {
2634
2617
CompilerAsserts .neverPartOfCompilation ();
2635
2618
// check if there is a live sentinel lock
2636
2619
PythonThreadState ts = threadStateMapping .get (thread );
@@ -2640,7 +2623,7 @@ public synchronized void disposeThread(Thread thread) {
2640
2623
}
2641
2624
ts .shutdown ();
2642
2625
threadStateMapping .remove (thread );
2643
- ts .dispose (this );
2626
+ ts .dispose (this , canRunGuestCode );
2644
2627
releaseSentinelLock (ts .sentinelLock );
2645
2628
getSharedMultiprocessingData ().removeChildContextThread (PThread .getThreadId (thread ));
2646
2629
}
0 commit comments