|
175 | 175 | import com.oracle.graal.python.util.PythonUtils; |
176 | 176 | import com.oracle.graal.python.util.ShutdownHook; |
177 | 177 | import com.oracle.graal.python.util.Supplier; |
| 178 | +import com.oracle.graal.python.util.SuppressFBWarnings; |
178 | 179 | import com.oracle.truffle.api.CallTarget; |
179 | 180 | import com.oracle.truffle.api.CompilerAsserts; |
180 | 181 | import com.oracle.truffle.api.CompilerDirectives; |
@@ -2480,9 +2481,26 @@ static final String dumpStackOnAssertionHelper(String msg) { |
2480 | 2481 | * @see GilNode |
2481 | 2482 | */ |
2482 | 2483 | @TruffleBoundary |
| 2484 | + // intentional catch of IllegalMonitorStateException, see inline comments |
| 2485 | + @SuppressFBWarnings("IMSE_DONT_CATCH_IMSE") |
2483 | 2486 | 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 | + } |
2486 | 2504 | } |
2487 | 2505 |
|
2488 | 2506 | /** |
|
0 commit comments