summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/internal/pycore_interp.h2
-rw-r--r--Include/internal/pycore_pylifecycle.h2
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst10
-rw-r--r--Objects/setobject.c25
-rw-r--r--Python/pylifecycle.c4
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);