@@ -77,10 +77,21 @@ typedef struct {
77
77
78
78
#define FI_FREELIST_MAXLEN 255
79
79
80
+ #ifdef Py_GIL_DISABLED
81
+ # define ASYNCIO_STATE_LOCK (state ) PyMutex_Lock(&state->mutex)
82
+ # define ASYNCIO_STATE_UNLOCK (state ) PyMutex_Unlock(&state->mutex)
83
+ #else
84
+ # define ASYNCIO_STATE_LOCK (state ) ((void)state)
85
+ # define ASYNCIO_STATE_UNLOCK (state ) ((void)state)
86
+ #endif
87
+
80
88
typedef struct futureiterobject futureiterobject ;
81
89
82
90
/* State of the _asyncio module */
83
91
typedef struct {
92
+ #ifdef Py_GIL_DISABLED
93
+ PyMutex mutex ;
94
+ #endif
84
95
PyTypeObject * FutureIterType ;
85
96
PyTypeObject * TaskStepMethWrapper_Type ;
86
97
PyTypeObject * FutureType ;
@@ -341,6 +352,8 @@ get_running_loop(asyncio_state *state, PyObject **loop)
341
352
}
342
353
}
343
354
355
+ // TODO GH-121621: This should be moved to PyThreadState
356
+ // for easier and quicker access.
344
357
state -> cached_running_loop = rl ;
345
358
state -> cached_running_loop_tsid = ts_id ;
346
359
}
@@ -384,6 +397,9 @@ set_running_loop(asyncio_state *state, PyObject *loop)
384
397
return -1 ;
385
398
}
386
399
400
+
401
+ // TODO GH-121621: This should be moved to PyThreadState
402
+ // for easier and quicker access.
387
403
state -> cached_running_loop = loop ; // borrowed, kept alive by ts_dict
388
404
state -> cached_running_loop_tsid = PyThreadState_GetID (tstate );
389
405
@@ -1664,6 +1680,7 @@ FutureIter_dealloc(futureiterobject *it)
1664
1680
state = get_asyncio_state (module );
1665
1681
}
1666
1682
1683
+ // TODO GH-121621: This should be moved to thread state as well.
1667
1684
if (state && state -> fi_freelist_len < FI_FREELIST_MAXLEN ) {
1668
1685
state -> fi_freelist_len ++ ;
1669
1686
it -> future = (FutureObj * ) state -> fi_freelist ;
@@ -2015,10 +2032,12 @@ static PyMethodDef TaskWakeupDef = {
2015
2032
static void
2016
2033
register_task (asyncio_state * state , TaskObj * task )
2017
2034
{
2035
+ ASYNCIO_STATE_LOCK (state );
2018
2036
assert (Task_Check (state , task ));
2019
2037
assert (task != & state -> asyncio_tasks .tail );
2020
2038
if (task -> next != NULL ) {
2021
2039
// already registered
2040
+ ASYNCIO_STATE_UNLOCK (state );
2022
2041
return ;
2023
2042
}
2024
2043
assert (task -> prev == NULL );
@@ -2027,6 +2046,7 @@ register_task(asyncio_state *state, TaskObj *task)
2027
2046
task -> next = state -> asyncio_tasks .head ;
2028
2047
state -> asyncio_tasks .head -> prev = task ;
2029
2048
state -> asyncio_tasks .head = task ;
2049
+ ASYNCIO_STATE_UNLOCK (state );
2030
2050
}
2031
2051
2032
2052
static int
@@ -2038,12 +2058,14 @@ register_eager_task(asyncio_state *state, PyObject *task)
2038
2058
static void
2039
2059
unregister_task (asyncio_state * state , TaskObj * task )
2040
2060
{
2061
+ ASYNCIO_STATE_LOCK (state );
2041
2062
assert (Task_Check (state , task ));
2042
2063
assert (task != & state -> asyncio_tasks .tail );
2043
2064
if (task -> next == NULL ) {
2044
2065
// not registered
2045
2066
assert (task -> prev == NULL );
2046
2067
assert (state -> asyncio_tasks .head != task );
2068
+ ASYNCIO_STATE_UNLOCK (state );
2047
2069
return ;
2048
2070
}
2049
2071
task -> next -> prev = task -> prev ;
@@ -2056,6 +2078,7 @@ unregister_task(asyncio_state *state, TaskObj *task)
2056
2078
task -> next = NULL ;
2057
2079
task -> prev = NULL ;
2058
2080
assert (state -> asyncio_tasks .head != task );
2081
+ ASYNCIO_STATE_UNLOCK (state );
2059
2082
}
2060
2083
2061
2084
static int
@@ -2210,7 +2233,12 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop,
2210
2233
// optimization: defer task name formatting
2211
2234
// store the task counter as PyLong in the name
2212
2235
// for deferred formatting in get_name
2213
- name = PyLong_FromUnsignedLongLong (++ state -> task_name_counter );
2236
+ #ifdef Py_GIL_DISABLED
2237
+ unsigned long long counter = _Py_atomic_add_uint64 (& state -> task_name_counter , 1 ) + 1 ;
2238
+ #else
2239
+ unsigned long long counter = ++ state -> task_name_counter ;
2240
+ #endif
2241
+ name = PyLong_FromUnsignedLongLong (counter );
2214
2242
} else if (!PyUnicode_CheckExact (name )) {
2215
2243
name = PyObject_Str (name );
2216
2244
} else {
0 commit comments