gh-128277: remove unnecessary critical section from socket.close (#128305)

Remove unnecessary critical section from `socket.close` as it now uses relaxed atomics for `sock_fd`.
This commit is contained in:
Kumar Aditya 2025-01-01 18:00:47 +05:30 committed by GitHub
parent d903b17499
commit bb9d955e16
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 23 additions and 11 deletions

View file

@ -7075,6 +7075,26 @@ class SendRecvFdsTests(unittest.TestCase):
self.assertEqual(data, str(index).encode()) self.assertEqual(data, str(index).encode())
class FreeThreadingTests(unittest.TestCase):
def test_close_detach_race(self):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def close():
for _ in range(1000):
s.close()
def detach():
for _ in range(1000):
s.detach()
t1 = threading.Thread(target=close)
t2 = threading.Thread(target=detach)
with threading_helper.start_threads([t1, t2]):
pass
def setUpModule(): def setUpModule():
thread_info = threading_helper.threading_setup() thread_info = threading_helper.threading_setup()
unittest.addModuleCleanup(threading_helper.threading_cleanup, *thread_info) unittest.addModuleCleanup(threading_helper.threading_cleanup, *thread_info)

View file

@ -6,7 +6,6 @@ preserve
# include "pycore_gc.h" // PyGC_Head # include "pycore_gc.h" // PyGC_Head
# include "pycore_runtime.h" // _Py_ID() # include "pycore_runtime.h" // _Py_ID()
#endif #endif
#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION()
#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() #include "pycore_modsupport.h" // _PyArg_UnpackKeywords()
PyDoc_STRVAR(_socket_socket_close__doc__, PyDoc_STRVAR(_socket_socket_close__doc__,
@ -26,13 +25,7 @@ _socket_socket_close_impl(PySocketSockObject *s);
static PyObject * static PyObject *
_socket_socket_close(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) _socket_socket_close(PySocketSockObject *s, PyObject *Py_UNUSED(ignored))
{ {
PyObject *return_value = NULL; return _socket_socket_close_impl(s);
Py_BEGIN_CRITICAL_SECTION(s);
return_value = _socket_socket_close_impl(s);
Py_END_CRITICAL_SECTION();
return return_value;
} }
static int static int
@ -287,4 +280,4 @@ exit:
#ifndef _SOCKET_SOCKET_IF_NAMETOINDEX_METHODDEF #ifndef _SOCKET_SOCKET_IF_NAMETOINDEX_METHODDEF
#define _SOCKET_SOCKET_IF_NAMETOINDEX_METHODDEF #define _SOCKET_SOCKET_IF_NAMETOINDEX_METHODDEF
#endif /* !defined(_SOCKET_SOCKET_IF_NAMETOINDEX_METHODDEF) */ #endif /* !defined(_SOCKET_SOCKET_IF_NAMETOINDEX_METHODDEF) */
/*[clinic end generated code: output=59c36bb31b05de68 input=a9049054013a1b77]*/ /*[clinic end generated code: output=3e612e8df1c322dd input=a9049054013a1b77]*/

View file

@ -3386,7 +3386,6 @@ sockets the address is a tuple (ifname, proto [,pkttype [,hatype [,addr]]])");
will surely fail. */ will surely fail. */
/*[clinic input] /*[clinic input]
@critical_section
_socket.socket.close _socket.socket.close
self as s: self(type="PySocketSockObject *") self as s: self(type="PySocketSockObject *")
@ -3397,7 +3396,7 @@ Close the socket. It cannot be used after this call.
static PyObject * static PyObject *
_socket_socket_close_impl(PySocketSockObject *s) _socket_socket_close_impl(PySocketSockObject *s)
/*[clinic end generated code: output=038b2418e07f6f6c input=9839a261e05bcb97]*/ /*[clinic end generated code: output=038b2418e07f6f6c input=dc487e470e55a83c]*/
{ {
SOCKET_T fd; SOCKET_T fd;
int res; int res;