Skip to content

Commit e2defcc

Browse files
committed
Fix GIL hold count assertion in PythonContext.releaseGil
1 parent 246e2c7 commit e2defcc

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@
175175
import com.oracle.graal.python.util.PythonUtils;
176176
import com.oracle.graal.python.util.ShutdownHook;
177177
import com.oracle.graal.python.util.Supplier;
178+
import com.oracle.graal.python.util.SuppressFBWarnings;
178179
import com.oracle.truffle.api.CallTarget;
179180
import com.oracle.truffle.api.CompilerAsserts;
180181
import com.oracle.truffle.api.CompilerDirectives;
@@ -2480,9 +2481,26 @@ static final String dumpStackOnAssertionHelper(String msg) {
24802481
* @see GilNode
24812482
*/
24822483
@TruffleBoundary
2484+
// intentional catch of IllegalMonitorStateException, see inline comments
2485+
@SuppressFBWarnings("IMSE_DONT_CATCH_IMSE")
24832486
void releaseGil() {
2484-
assert globalInterpreterLock.getHoldCount() == 1 : dumpStackOnAssertionHelper("trying to release the GIL with invalid hold count " + globalInterpreterLock.getHoldCount());
2485-
globalInterpreterLock.unlock();
2487+
// We allow hold count == 0 when cancelling, because a thread may have given up the GIL,
2488+
// then a cancelling (subclass of ThreadDeath) exception is thrown inside the code running
2489+
// without GIL through thread local action and in such case, we do not try to reacquire the
2490+
// GIL and let the ThreadDeath bubble up the stack to the top level and along the way we
2491+
// may have some finally blocks that are trying to release the initially acquired GIL and
2492+
// reach this method
2493+
assert globalInterpreterLock.getHoldCount() == 1 || (env.getContext().isCancelling() && globalInterpreterLock.getHoldCount() == 0) : dumpStackOnAssertionHelper(
2494+
"trying to release the GIL with invalid hold count " + globalInterpreterLock.getHoldCount());
2495+
try {
2496+
globalInterpreterLock.unlock();
2497+
} catch (IllegalMonitorStateException ex) {
2498+
// IllegalMonitorStateException is thrown if the lock is not owned by this thread, see
2499+
// the comment above why we allow it if the context is cancelling
2500+
if (!env.getContext().isCancelling()) {
2501+
throw ex;
2502+
}
2503+
}
24862504
}
24872505

24882506
/**

0 commit comments

Comments
 (0)