diff options
-rw-r--r-- | Include/internal/pycore_interp.h | 2 | ||||
-rw-r--r-- | Include/internal/pycore_pylifecycle.h | 2 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst | 10 | ||||
-rw-r--r-- | Objects/setobject.c | 25 | ||||
-rw-r--r-- | Python/pylifecycle.c | 4 |
5 files changed, 24 insertions, 19 deletions
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 3f64edc..697d97a 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -238,6 +238,8 @@ struct _is { /* Using a cache is very effective since typically only a single slice is created and then deleted again. */ PySliceObject *slice_cache; + // The empty frozenset is a singleton. + PyObject *empty_frozenset; struct _Py_tuple_state tuple; struct _Py_list_state list; diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index dc99737..83ce1d2 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -62,7 +62,7 @@ extern void _PyFrame_Fini(PyThreadState *tstate); extern void _PyDict_Fini(PyThreadState *tstate); extern void _PyTuple_Fini(PyThreadState *tstate); extern void _PyList_Fini(PyThreadState *tstate); -extern void _PySet_Fini(void); +extern void _PySet_Fini(PyThreadState *tstate); extern void _PyBytes_Fini(void); extern void _PyFloat_Fini(PyThreadState *tstate); extern void _PySlice_Fini(PyThreadState *tstate); diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst index 3406ca8..24fd437 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst @@ -1,5 +1,5 @@ -The tuple free lists, the empty tuple singleton, the list free list, the float -free list, the slice cache, the dict free lists, the frame free list, the -asynchronous generator free lists, and the context free list are no longer -shared by all interpreters: each interpreter now its has own free lists and -caches. +The tuple free lists, the empty tuple singleton, the list free list, the empty +frozenset singleton, the float free list, the slice cache, the dict free lists, +the frame free list, the asynchronous generator free lists, and the context +free list are no longer shared by all interpreters: each interpreter now its +has own free lists and caches. diff --git a/Objects/setobject.c b/Objects/setobject.c index 76b1944..69bfc7d 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -975,12 +975,11 @@ make_new_set_basetype(PyTypeObject *type, PyObject *iterable) return make_new_set(type, iterable); } -/* The empty frozenset is a singleton */ -static PyObject *emptyfrozenset = NULL; - static PyObject * make_new_frozenset(PyTypeObject *type, PyObject *iterable) { + PyObject *res; + if (type != &PyFrozenSet_Type) { return make_new_set(type, iterable); } @@ -991,7 +990,7 @@ make_new_frozenset(PyTypeObject *type, PyObject *iterable) Py_INCREF(iterable); return iterable; } - PyObject *res = make_new_set((PyTypeObject *)type, iterable); + res = make_new_set((PyTypeObject *)type, iterable); if (res == NULL || PySet_GET_SIZE(res) != 0) { return res; } @@ -1000,11 +999,17 @@ make_new_frozenset(PyTypeObject *type, PyObject *iterable) } // The empty frozenset is a singleton - if (emptyfrozenset == NULL) { - emptyfrozenset = make_new_set((PyTypeObject *)type, NULL); + PyInterpreterState *interp = _PyInterpreterState_GET(); + res = interp->empty_frozenset; + if (res == NULL) { + interp->empty_frozenset = make_new_set((PyTypeObject *)type, NULL); + res = interp->empty_frozenset; + if (res == NULL) { + return NULL; + } } - Py_XINCREF(emptyfrozenset); - return emptyfrozenset; + Py_INCREF(res); + return res; } static PyObject * @@ -2300,9 +2305,9 @@ PySet_Add(PyObject *anyset, PyObject *key) } void -_PySet_Fini(void) +_PySet_Fini(PyThreadState *tstate) { - Py_CLEAR(emptyfrozenset); + Py_CLEAR(tstate->interp->empty_frozenset); } int diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 1b4a3db..aaea045 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1255,9 +1255,7 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) _PyAsyncGen_Fini(tstate); _PyContext_Fini(tstate); - if (is_main_interp) { - _PySet_Fini(); - } + _PySet_Fini(tstate); _PyDict_Fini(tstate); _PyList_Fini(tstate); _PyTuple_Fini(tstate); |