mirror of https://github.com/python/cpython
gh-117657: Use critical section to make _socket.socket.close thread safe (GH-120490)
This commit is contained in:
parent
c7991cc287
commit
8a5176772c
|
@ -6,8 +6,35 @@ preserve
|
|||
# include "pycore_gc.h" // PyGC_Head
|
||||
# include "pycore_runtime.h" // _Py_ID()
|
||||
#endif
|
||||
#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION()
|
||||
#include "pycore_modsupport.h" // _PyArg_UnpackKeywords()
|
||||
|
||||
PyDoc_STRVAR(_socket_socket_close__doc__,
|
||||
"close($self, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"close()\n"
|
||||
"\n"
|
||||
"Close the socket. It cannot be used after this call.");
|
||||
|
||||
#define _SOCKET_SOCKET_CLOSE_METHODDEF \
|
||||
{"close", (PyCFunction)_socket_socket_close, METH_NOARGS, _socket_socket_close__doc__},
|
||||
|
||||
static PyObject *
|
||||
_socket_socket_close_impl(PySocketSockObject *s);
|
||||
|
||||
static PyObject *
|
||||
_socket_socket_close(PySocketSockObject *s, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
|
||||
Py_BEGIN_CRITICAL_SECTION(s);
|
||||
return_value = _socket_socket_close_impl(s);
|
||||
Py_END_CRITICAL_SECTION();
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
static int
|
||||
sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto,
|
||||
PyObject *fdobj);
|
||||
|
@ -259,4 +286,4 @@ exit:
|
|||
#ifndef _SOCKET_SOCKET_IF_NAMETOINDEX_METHODDEF
|
||||
#define _SOCKET_SOCKET_IF_NAMETOINDEX_METHODDEF
|
||||
#endif /* !defined(_SOCKET_SOCKET_IF_NAMETOINDEX_METHODDEF) */
|
||||
/*[clinic end generated code: output=eb37b5d88a1e4661 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=6037e47b012911c5 input=a9049054013a1b77]*/
|
||||
|
|
|
@ -3331,8 +3331,19 @@ sockets the address is a tuple (ifname, proto [,pkttype [,hatype [,addr]]])");
|
|||
Set the file descriptor to -1 so operations tried subsequently
|
||||
will surely fail. */
|
||||
|
||||
/*[clinic input]
|
||||
@critical_section
|
||||
_socket.socket.close
|
||||
self as s: self(type="PySocketSockObject *")
|
||||
|
||||
close()
|
||||
|
||||
Close the socket. It cannot be used after this call.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
sock_close(PySocketSockObject *s, PyObject *Py_UNUSED(ignored))
|
||||
_socket_socket_close_impl(PySocketSockObject *s)
|
||||
/*[clinic end generated code: output=038b2418e07f6f6c input=9839a261e05bcb97]*/
|
||||
{
|
||||
SOCKET_T fd;
|
||||
int res;
|
||||
|
@ -3357,11 +3368,6 @@ sock_close(PySocketSockObject *s, PyObject *Py_UNUSED(ignored))
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(sock_close_doc,
|
||||
"close()\n\
|
||||
\n\
|
||||
Close the socket. It cannot be used after this call.");
|
||||
|
||||
static PyObject *
|
||||
sock_detach(PySocketSockObject *s, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
|
@ -5118,8 +5124,7 @@ static PyMethodDef sock_methods[] = {
|
|||
{"bind", (PyCFunction)sock_bind, METH_O,
|
||||
bind_doc},
|
||||
#endif
|
||||
{"close", (PyCFunction)sock_close, METH_NOARGS,
|
||||
sock_close_doc},
|
||||
_SOCKET_SOCKET_CLOSE_METHODDEF
|
||||
#ifdef HAVE_CONNECT
|
||||
{"connect", (PyCFunction)sock_connect, METH_O,
|
||||
connect_doc},
|
||||
|
|
|
@ -54,7 +54,6 @@ race_top:PyInterpreterState_ThreadHead
|
|||
race_top:_PyObject_TryGetInstanceAttribute
|
||||
race_top:PyThreadState_Next
|
||||
race_top:PyUnstable_InterpreterFrame_GetLine
|
||||
race_top:sock_close
|
||||
race_top:tstate_delete_common
|
||||
race_top:tstate_is_freed
|
||||
race_top:type_modified_unlocked
|
||||
|
|
Loading…
Reference in New Issue