]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-40521: Make the empty frozenset per interpreter (GH-21068)
authorVictor Stinner <vstinner@python.org>
Tue, 23 Jun 2020 12:07:52 +0000 (14:07 +0200)
committerGitHub <noreply@github.com>
Tue, 23 Jun 2020 12:07:52 +0000 (14:07 +0200)
Each interpreter now has its own empty frozenset singleton.

Include/internal/pycore_interp.h
Include/internal/pycore_pylifecycle.h
Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst
Objects/setobject.c
Python/pylifecycle.c

index 3f64edcee983ba144ca99e4db5b7fce97678ee8b..697d97a39e01fb08e1fc68a8378b5a906462b7ad 100644 (file)
@@ -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;
index dc9973782977224da0b1751e09091dc561f12290..83ce1d2e7468c04e1359ea0d41752c36f0a9b2f0 100644 (file)
@@ -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);
index 3406ca8c973d8b475f04bc630327c35952d1dd90..24fd437062a51f732fc618561217c53f44b1dccd 100644 (file)
@@ -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.
index 76b1944db455886d68ce7ab56fb6d5b1ba0b23ad..69bfc7d0a58fb23c1cf72e682fe8ca2add7a84ec 100644 (file)
@@ -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
index 1b4a3db517c1d10279d02f1ac17ab0cd15129518..aaea0454d00844c330b67889ba49a9652249452f 100644 (file)
@@ -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);