From f243dbd7d743cf6a5d64559d3ec4eb1929f6042e Mon Sep 17 00:00:00 2001 From: HUANG Jiaqi Date: Wed, 15 Nov 2023 18:31:30 +0800 Subject: [PATCH 1/5] gh-112070: make `functools.lrucacle` threadsafe in --disable-gil build --- Modules/_functoolsmodule.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index ca440e4c70c0d9..12a7107a6d8ed9 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -6,6 +6,7 @@ #include "pycore_object.h" // _PyObject_GC_TRACK #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_tuple.h" // _PyTuple_ITEMS() +#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION #include "clinic/_functoolsmodule.c.h" @@ -1274,7 +1275,11 @@ lru_cache_dealloc(lru_cache_object *obj) static PyObject * lru_cache_call(lru_cache_object *self, PyObject *args, PyObject *kwds) { - return self->wrapper(self, args, kwds); + PyObject* result; + Py_BEGIN_CRITICAL_SECTION(self); + result = self->wrapper(self, args, kwds); + Py_END_CRITICAL_SECTION(); + return result; } static PyObject * @@ -1287,6 +1292,7 @@ lru_cache_descr_get(PyObject *self, PyObject *obj, PyObject *type) } /*[clinic input] +@critical_section _functools._lru_cache_wrapper.cache_info Report cache statistics @@ -1308,6 +1314,7 @@ _functools__lru_cache_wrapper_cache_info_impl(PyObject *self) } /*[clinic input] +@critical_section _functools._lru_cache_wrapper.cache_clear Clear the cache and cache statistics From 3bddf43f24bf40277c559c7cb16e4f8175b7dc15 Mon Sep 17 00:00:00 2001 From: HUANG Jiaqi Date: Wed, 15 Nov 2023 20:22:33 +0800 Subject: [PATCH 2/5] gh-112070: update generate `functoolsmodule` files --- Modules/_functoolsmodule.c | 4 ++-- Modules/clinic/_functoolsmodule.c.h | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 12a7107a6d8ed9..e275395a866f3f 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -1300,7 +1300,7 @@ Report cache statistics static PyObject * _functools__lru_cache_wrapper_cache_info_impl(PyObject *self) -/*[clinic end generated code: output=cc796a0b06dbd717 input=f05e5b6ebfe38645]*/ +/*[clinic end generated code: output=cc796a0b06dbd717 input=00e1acb31aa21ecc]*/ { lru_cache_object *_self = (lru_cache_object *) self; if (_self->maxsize == -1) { @@ -1322,7 +1322,7 @@ Clear the cache and cache statistics static PyObject * _functools__lru_cache_wrapper_cache_clear_impl(PyObject *self) -/*[clinic end generated code: output=58423b35efc3e381 input=6ca59dba09b12584]*/ +/*[clinic end generated code: output=58423b35efc3e381 input=dfa33acbecf8b4b2]*/ { lru_cache_object *_self = (lru_cache_object *) self; lru_list_elem *list = lru_cache_unlink_list(_self); diff --git a/Modules/clinic/_functoolsmodule.c.h b/Modules/clinic/_functoolsmodule.c.h index 94f7a23e8f217a..11fe0439c08a5e 100644 --- a/Modules/clinic/_functoolsmodule.c.h +++ b/Modules/clinic/_functoolsmodule.c.h @@ -81,7 +81,13 @@ _functools__lru_cache_wrapper_cache_info_impl(PyObject *self); static PyObject * _functools__lru_cache_wrapper_cache_info(PyObject *self, PyObject *Py_UNUSED(ignored)) { - return _functools__lru_cache_wrapper_cache_info_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _functools__lru_cache_wrapper_cache_info_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_functools__lru_cache_wrapper_cache_clear__doc__, @@ -99,6 +105,12 @@ _functools__lru_cache_wrapper_cache_clear_impl(PyObject *self); static PyObject * _functools__lru_cache_wrapper_cache_clear(PyObject *self, PyObject *Py_UNUSED(ignored)) { - return _functools__lru_cache_wrapper_cache_clear_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _functools__lru_cache_wrapper_cache_clear_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } -/*[clinic end generated code: output=231403340a20e31b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5e3207fa0d28cdb1 input=a9049054013a1b77]*/ From 9d75348a9595b28ea3e0f4d7a8cce75e0e891322 Mon Sep 17 00:00:00 2001 From: HUANG Jiaqi Date: Wed, 15 Nov 2023 20:21:14 +0800 Subject: [PATCH 3/5] gh-112070: add NEWS file --- .../next/Library/2023-11-15-20-19-45.gh-issue-112070.q6OhcU.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2023-11-15-20-19-45.gh-issue-112070.q6OhcU.rst diff --git a/Misc/NEWS.d/next/Library/2023-11-15-20-19-45.gh-issue-112070.q6OhcU.rst b/Misc/NEWS.d/next/Library/2023-11-15-20-19-45.gh-issue-112070.q6OhcU.rst new file mode 100644 index 00000000000000..da12d835389565 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-15-20-19-45.gh-issue-112070.q6OhcU.rst @@ -0,0 +1 @@ +make ``functools.lru_cache`` threadsafe in ``--disable-gil`` build. From e977bc4e22ce5fe36dc9de9604d9af6312fa0cff Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Wed, 15 Nov 2023 18:10:54 -0500 Subject: [PATCH 4/5] Delete Misc/NEWS.d/next/Library/2023-11-15-20-19-45.gh-issue-112070.q6OhcU.rst --- .../next/Library/2023-11-15-20-19-45.gh-issue-112070.q6OhcU.rst | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Misc/NEWS.d/next/Library/2023-11-15-20-19-45.gh-issue-112070.q6OhcU.rst diff --git a/Misc/NEWS.d/next/Library/2023-11-15-20-19-45.gh-issue-112070.q6OhcU.rst b/Misc/NEWS.d/next/Library/2023-11-15-20-19-45.gh-issue-112070.q6OhcU.rst deleted file mode 100644 index da12d835389565..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-11-15-20-19-45.gh-issue-112070.q6OhcU.rst +++ /dev/null @@ -1 +0,0 @@ -make ``functools.lru_cache`` threadsafe in ``--disable-gil`` build. From 0fc873cc89d53f6b0204a303fefeeefdb9323f57 Mon Sep 17 00:00:00 2001 From: HUANG Jiaqi Date: Thu, 16 Nov 2023 10:17:52 +0800 Subject: [PATCH 5/5] gh-112070: reformat functoolsmodule.c --- Modules/_functoolsmodule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index e275395a866f3f..2592c4d7f75631 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -1,12 +1,12 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION #include "pycore_dict.h" // _PyDict_Pop_KnownHash() #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_object.h" // _PyObject_GC_TRACK #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_tuple.h" // _PyTuple_ITEMS() -#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION #include "clinic/_functoolsmodule.c.h" @@ -1275,7 +1275,7 @@ lru_cache_dealloc(lru_cache_object *obj) static PyObject * lru_cache_call(lru_cache_object *self, PyObject *args, PyObject *kwds) { - PyObject* result; + PyObject *result; Py_BEGIN_CRITICAL_SECTION(self); result = self->wrapper(self, args, kwds); Py_END_CRITICAL_SECTION();