Skip to content

Commit 0c8231a

Browse files
Track active status.
1 parent 5282295 commit 0c8231a

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

Include/cpython/pystate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ struct _ts {
130130
unsigned int bound:1;
131131
/* Has been unbound from its OS thread. */
132132
unsigned int unbound:1;
133+
/* Currently in use (maybe holds the GIL). */
134+
unsigned int active:1;
133135

134136
/* various stages of finalization */
135137
unsigned int finalizing:1;

Python/pystate.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,10 +1276,6 @@ PyThreadState_Clear(PyThreadState *tstate)
12761276
* for the main interpreter, current_fast_get() must be the main thread
12771277
*/
12781278

1279-
// The GIL must be held by the current thread,
1280-
// which must not be the target.
1281-
// XXX Enforce that (check current_fast_get()).
1282-
12831279
int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose;
12841280

12851281
if (verbose && tstate->cframe->current_frame != NULL) {
@@ -1536,6 +1532,26 @@ PyThreadState_GetID(PyThreadState *tstate)
15361532
}
15371533

15381534

1535+
static inline void
1536+
tstate_activate(PyThreadState *tstate)
1537+
{
1538+
assert(tstate != NULL);
1539+
assert(tstate_is_alive(tstate) && tstate_is_bound(tstate));
1540+
assert(!tstate->_status.active);
1541+
tstate->_status.active = 1;
1542+
}
1543+
1544+
static inline void
1545+
tstate_deactivate(PyThreadState *tstate)
1546+
{
1547+
assert(tstate != NULL);
1548+
assert(tstate_is_bound(tstate));
1549+
// XXX assert(tstate_is_alive(tstate) && tstate_is_bound(tstate));
1550+
assert(tstate->_status.active);
1551+
tstate->_status.active = 0;
1552+
}
1553+
1554+
15391555
//----------
15401556
// other API
15411557
//----------
@@ -1612,15 +1628,19 @@ PyThreadState *
16121628
_PyThreadState_Swap(_PyRuntimeState *runtime, PyThreadState *newts)
16131629
{
16141630
PyThreadState *oldts = current_fast_get(runtime);
1615-
// XXX assert(oldts == NULL || tstate_is_alive(oldts));
16161631
// XXX tstate_is_bound(oldts)
1632+
if (oldts != NULL) {
1633+
// XXX assert(oldts == NULL || tstate_is_alive(oldts));
1634+
tstate_deactivate(oldts);
1635+
}
16171636

16181637
if (newts == NULL) {
16191638
current_fast_clear(runtime);
16201639
}
16211640
else {
16221641
assert(tstate_is_alive(newts) && tstate_is_bound(newts));
16231642
current_fast_set(runtime, newts);
1643+
tstate_activate(newts);
16241644
}
16251645

16261646
/* It should not be possible for more than one thread state

0 commit comments

Comments
 (0)