@@ -143,59 +143,57 @@ void pybind11GuardDisarm(G& guard)
143143// / RAII utility type that guarantees that the GIL is locked for the scope of
144144// / the lifetime of the object.
145145// /
146+ // / Objects of this type (or objects composed of them) must not be kept alive
147+ // / after the hand is given back to the interpreter.
148+ // /
146149// / This type is re-entrant.
147150// /
148- // / postcondition: `GILAcquire acq;` establishes `currentThreadHoldsGil()`
151+ // / postcondition: `GILAcquire acq;` establishes
152+ // / `(interpreterIsFinalizing() && *interpreterIsFinalizing()) || currentThreadHoldsGil()`
149153struct GILAcquire
150154{
151155 inline GILAcquire ()
152156 {
157+ const auto optIsFinalizing = interpreterIsFinalizing ();
158+ const auto definitelyFinalizing = optIsFinalizing && *optIsFinalizing;
153159 // `gil_scoped_acquire` is re-entrant by itself, so we don't need to check
154160 // whether or not the GIL is already held by the current thread.
155- QI_ASSERT (currentThreadHoldsGil ());
161+ if (!definitelyFinalizing)
162+ _acq.emplace ();
163+ QI_ASSERT (definitelyFinalizing || currentThreadHoldsGil ());
156164 }
157165
158166 GILAcquire (const GILAcquire&) = delete ;
159167 GILAcquire& operator =(const GILAcquire&) = delete ;
160168
161- inline ~GILAcquire ()
162- {
163- const auto optIsFinalizing = interpreterIsFinalizing ();
164- const auto definitelyFinalizing = optIsFinalizing && *optIsFinalizing;
165- if (definitelyFinalizing)
166- detail::pybind11GuardDisarm (_acq);
167- }
168-
169169private:
170- pybind11::gil_scoped_acquire _acq;
170+ boost::optional< pybind11::gil_scoped_acquire> _acq;
171171};
172172
173173// / RAII utility type that guarantees that the GIL is unlocked for the scope of
174174// / the lifetime of the object.
175175// /
176+ // / Objects of this type (or objects composed of them) must not be kept alive
177+ // / after the hand is given back to the interpreter.
178+ // /
176179// / This type is re-entrant.
177180// /
178- // / postcondition: `GILRelease rel;` establishes `!currentThreadHoldsGil()`
181+ // / postcondition: `GILRelease rel;` establishes
182+ // / `(interpreterIsFinalizing() && *interpreterIsFinalizing()) || !currentThreadHoldsGil()`
179183struct GILRelease
180184{
181185 inline GILRelease ()
182186 {
183- if (currentThreadHoldsGil ())
187+ const auto optIsFinalizing = interpreterIsFinalizing ();
188+ const auto definitelyFinalizing = optIsFinalizing && *optIsFinalizing;
189+ if (!definitelyFinalizing && currentThreadHoldsGil ())
184190 _release.emplace ();
185- QI_ASSERT (!currentThreadHoldsGil ());
191+ QI_ASSERT (definitelyFinalizing || !currentThreadHoldsGil ());
186192 }
187193
188194 GILRelease (const GILRelease&) = delete ;
189195 GILRelease& operator =(const GILRelease&) = delete ;
190196
191- inline ~GILRelease ()
192- {
193- const auto optIsFinalizing = interpreterIsFinalizing ();
194- const auto definitelyFinalizing = optIsFinalizing && *optIsFinalizing;
195- if (_release && definitelyFinalizing)
196- detail::pybind11GuardDisarm (*_release);
197- }
198-
199197private:
200198 boost::optional<pybind11::gil_scoped_release> _release;
201199};
0 commit comments