Commit 95df334
committed
Reworks GIL related types to prevent some forms of program termination.
This change is a rework of some GIL related types in the library to prevent and avoid some unexpected crashes and program terminations, which would occur most often at process exit:
- A new exception type named `InterpreterFinalizingException` is introduced. It is thrown by some functions in the library when an operation fails because the interpreter is currently finalizing.
- `GILAcquire` constructor now throws a `InterpreterFinalizingException` when the interpreter is finalizing and therefore the GIL could not be acquired.
- `GILRelease` destructor now does not reacquire the GIL when the interpreter is finalizing.
- The `Guarded` and `GILGuardedObject` types are removed, and replaced with a `SharedObject` type. This type now wraps a Python object value as a shared reference-counted value that does not require the GIL to copy or move. The last copy of a `SharedObject` value will acquire the GIL to release the object, if possible, or do nothing (and leak it) if the GIL cannot be acquired.
- The `DeleteInOtherThread` deleter type is removed. Its implementation was incorrect and it has become unneeded.
- Destructors of `Application` and `ApplicationSession` do not use the `DeleterInOtherThread` deleter type anymore. The hypothesis is that the `DeleteInOtherThread` deleter was previously needed because `Application` values were wrapped in shared pointers and could be destroyed in callbacks executed by native threads. This is not the case anymore and instead, they destroy the application in the same thread that the Python `Application` object is garbage collected, which most likely is the interpreter main thread (due to `Application` being a singleton in the Python code, and its destruction is scheduled in an `atexit` callback).
- A new `invokeCatchPythonError` is introduced. It acquires the GIL, then invokes a function with the given arguments, but catches any `pybind11::error_already_set` exception thrown during this invocation, and throws a `std::runtime_error` instead.
- The `currentThreadHoldsGil` function now returns an optional denoting if the interpreter is initialized and not finalizing. Another function `gilExistsAndCurrentThreadHoldsIt` is introduced that returns just a bool.
- The `ObjectDecRef` internal type is removed, as it is unused.
This change mitigates the problem observed in issue #SW-4658.1 parent f2e6d0a commit 95df334
12 files changed
Lines changed: 366 additions & 243 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
115 | 115 | | |
116 | 116 | | |
117 | 117 | | |
| 118 | + | |
118 | 119 | | |
119 | 120 | | |
120 | 121 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
125 | 125 | | |
126 | 126 | | |
127 | 127 | | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
128 | 150 | | |
129 | 151 | | |
130 | 152 | | |
| |||
203 | 225 | | |
204 | 226 | | |
205 | 227 | | |
| 228 | + | |
| 229 | + | |
206 | 230 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
0 commit comments