From 8f635f442d8f3ba35bbc6fed937b8ee394058662 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Sun, 13 Mar 2022 19:13:24 +0200 Subject: [PATCH 1/5] Cleanup _overlapped module --- Modules/clinic/overlapped.c.h | 67 +++++++++++++++++-------- Modules/overlapped.c | 92 +++++++++++++++-------------------- 2 files changed, 84 insertions(+), 75 deletions(-) diff --git a/Modules/clinic/overlapped.c.h b/Modules/clinic/overlapped.c.h index 16d6013ef2f2e5..7e81fc8f97104f 100644 --- a/Modules/clinic/overlapped.c.h +++ b/Modules/clinic/overlapped.c.h @@ -466,22 +466,27 @@ PyDoc_STRVAR(_overlapped_Overlapped_ReadFileInto__doc__, static PyObject * _overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj); + HANDLE handle, Py_buffer *bufobj); static PyObject * _overlapped_Overlapped_ReadFileInto(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O:ReadFileInto", + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*:ReadFileInto", &handle, &bufobj)) { goto exit; } - return_value = _overlapped_Overlapped_ReadFileInto_impl(self, handle, bufobj); + return_value = _overlapped_Overlapped_ReadFileInto_impl(self, handle, &bufobj); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -527,7 +532,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSARecvInto__doc__, static PyObject * _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj, + HANDLE handle, Py_buffer *bufobj, DWORD flags); static PyObject * @@ -535,16 +540,21 @@ _overlapped_Overlapped_WSARecvInto(OverlappedObject *self, PyObject *const *args { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; DWORD flags; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"Ok:WSARecvInto", + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*k:WSARecvInto", &handle, &bufobj, &flags)) { goto exit; } - return_value = _overlapped_Overlapped_WSARecvInto_impl(self, handle, bufobj, flags); + return_value = _overlapped_Overlapped_WSARecvInto_impl(self, handle, &bufobj, flags); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -559,22 +569,27 @@ PyDoc_STRVAR(_overlapped_Overlapped_WriteFile__doc__, static PyObject * _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj); + Py_buffer *bufobj); static PyObject * _overlapped_Overlapped_WriteFile(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O:WriteFile", + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*:WriteFile", &handle, &bufobj)) { goto exit; } - return_value = _overlapped_Overlapped_WriteFile_impl(self, handle, bufobj); + return_value = _overlapped_Overlapped_WriteFile_impl(self, handle, &bufobj); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -589,23 +604,28 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSASend__doc__, static PyObject * _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags); + Py_buffer *bufobj, DWORD flags); static PyObject * _overlapped_Overlapped_WSASend(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; DWORD flags; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"Ok:WSASend", + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*k:WSASend", &handle, &bufobj, &flags)) { goto exit; } - return_value = _overlapped_Overlapped_WSASend_impl(self, handle, bufobj, flags); + return_value = _overlapped_Overlapped_WSASend_impl(self, handle, &bufobj, flags); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -852,7 +872,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSASendTo__doc__, static PyObject * _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags, + Py_buffer *bufobj, DWORD flags, PyObject *AddressObj); static PyObject * @@ -860,17 +880,22 @@ _overlapped_Overlapped_WSASendTo(OverlappedObject *self, PyObject *const *args, { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; DWORD flags; PyObject *AddressObj; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"OkO:WSASendTo", + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*kO:WSASendTo", &handle, &bufobj, &flags, &AddressObj)) { goto exit; } - return_value = _overlapped_Overlapped_WSASendTo_impl(self, handle, bufobj, flags, AddressObj); + return_value = _overlapped_Overlapped_WSASendTo_impl(self, handle, &bufobj, flags, AddressObj); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -943,4 +968,4 @@ _overlapped_Overlapped_WSARecvFromInto(OverlappedObject *self, PyObject *const * return return_value; } -/*[clinic end generated code: output=5c9b17890ef29d52 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d19a061ea7398d23 input=a9049054013a1b77]*/ diff --git a/Modules/overlapped.c b/Modules/overlapped.c index ab9a2f0ce26f62..e6e991dd6df1d6 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -150,7 +150,6 @@ static LPFN_ACCEPTEX Py_AcceptEx = NULL; static LPFN_CONNECTEX Py_ConnectEx = NULL; static LPFN_DISCONNECTEX Py_DisconnectEx = NULL; static LPFN_TRANSMITFILE Py_TransmitFile = NULL; -static BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED) = NULL; #define GET_WSA_POINTER(s, x) \ (SOCKET_ERROR != WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ @@ -168,6 +167,16 @@ initialize_function_pointers(void) SOCKET s; DWORD dwBytes; + if (Py_AcceptEx != NULL && + Py_ConnectEx != NULL && + Py_DisconnectEx != NULL && + Py_TransmitFile != NULL) + { + // All function pointers are initialized already + // by previous module import + return 0; + } + s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == INVALID_SOCKET) { SetFromWindowsErr(WSAGetLastError()); @@ -185,12 +194,6 @@ initialize_function_pointers(void) } closesocket(s); - - /* On WinXP we will have Py_CancelIoEx == NULL */ - Py_BEGIN_ALLOW_THREADS - hKernel32 = GetModuleHandle("KERNEL32"); - *(FARPROC *)&Py_CancelIoEx = GetProcAddress(hKernel32, "CancelIoEx"); - Py_END_ALLOW_THREADS return 0; } @@ -596,7 +599,7 @@ _overlapped_FormatMessage_impl(PyObject *module, DWORD code) * Mark operation as completed - used when reading produces ERROR_BROKEN_PIPE */ -static void +static inline void mark_as_completed(OVERLAPPED *ov) { ov->Internal = 0; @@ -704,7 +707,7 @@ Overlapped_dealloc(OverlappedObject *self) if (!HasOverlappedIoCompleted(&self->overlapped) && self->type != TYPE_NOT_STARTED) { - if (Py_CancelIoEx && Py_CancelIoEx(self->handle, &self->overlapped)) + if (CancelIoEx(self->handle, &self->overlapped)) wait = TRUE; Py_BEGIN_ALLOW_THREADS @@ -820,10 +823,7 @@ _overlapped_Overlapped_cancel_impl(OverlappedObject *self) if (!HasOverlappedIoCompleted(&self->overlapped)) { Py_BEGIN_ALLOW_THREADS - if (Py_CancelIoEx) - ret = Py_CancelIoEx(self->handle, &self->overlapped); - else - ret = CancelIo(self->handle); + ret = CancelIoEx(self->handle, &self->overlapped); Py_END_ALLOW_THREADS } @@ -1034,7 +1034,7 @@ _overlapped_Overlapped_ReadFile_impl(OverlappedObject *self, HANDLE handle, _overlapped.Overlapped.ReadFileInto handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer / Start overlapped receive. @@ -1042,24 +1042,21 @@ Start overlapped receive. static PyObject * _overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj) -/*[clinic end generated code: output=1e9e712e742e5b2a input=16f6cc268d1d0387]*/ + HANDLE handle, Py_buffer *bufobj) +/*[clinic end generated code: output=8754744506023071 input=4f037ba09939e32d]*/ { if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + self->user_buffer = bufobj; self->type = TYPE_READINTO; self->handle = handle; @@ -1142,7 +1139,7 @@ _overlapped_Overlapped_WSARecv_impl(OverlappedObject *self, HANDLE handle, _overlapped.Overlapped.WSARecvInto handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer flags: DWORD / @@ -1151,25 +1148,22 @@ Start overlapped receive. static PyObject * _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj, + HANDLE handle, Py_buffer *bufobj, DWORD flags) -/*[clinic end generated code: output=9a438abc436fe87c input=4f87c38fc381d525]*/ +/*[clinic end generated code: output=59ae7688786cf86b input=73e7fa00db633edd]*/ { if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + self->user_buffer = bufobj; self->type = TYPE_READINTO; self->handle = handle; @@ -1182,7 +1176,7 @@ _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, _overlapped.Overlapped.WriteFile handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer / Start overlapped write. @@ -1190,8 +1184,8 @@ Start overlapped write. static PyObject * _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj) -/*[clinic end generated code: output=c376230b6120d877 input=b8d9a7608d8a1e72]*/ + Py_buffer *bufobj) +/*[clinic end generated code: output=fa5d5880a1bf04b1 input=ac54424c362abfc1]*/ { DWORD written; BOOL ret; @@ -1202,16 +1196,13 @@ _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + self->user_buffer = bufobj; self->type = TYPE_WRITE; self->handle = handle; @@ -1237,7 +1228,7 @@ _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, _overlapped.Overlapped.WSASend handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer flags: DWORD / @@ -1246,8 +1237,8 @@ Start overlapped send. static PyObject * _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags) -/*[clinic end generated code: output=316031c7467040cc input=932e7cba6d18f708]*/ + Py_buffer *bufobj, DWORD flags) +/*[clinic end generated code: output=3baaa6e1f7fe229e input=c4167420ba2f93d8]*/ { DWORD written; WSABUF wsabuf; @@ -1259,16 +1250,13 @@ _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + self->user_buffer = bufobj; self->type = TYPE_WRITE; self->handle = handle; @@ -1728,7 +1716,7 @@ _overlapped_WSAConnect_impl(PyObject *module, HANDLE ConnectSocket, _overlapped.Overlapped.WSASendTo handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer flags: DWORD address_as_bytes as AddressObj: object / @@ -1738,9 +1726,9 @@ Start overlapped sendto over a connectionless (UDP) socket. static PyObject * _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags, + Py_buffer *bufobj, DWORD flags, PyObject *AddressObj) -/*[clinic end generated code: output=fe0ff55eb60d65e1 input=f709e6ecebd9bc18]*/ +/*[clinic end generated code: output=3cdedc4cfaeb70cd input=b7c1749a62e2e374]*/ { char AddressBuf[sizeof(struct sockaddr_in6)]; SOCKADDR *Address = (SOCKADDR*)AddressBuf; @@ -1762,17 +1750,13 @@ _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) { - return NULL; - } - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + self->user_buffer = bufobj; self->type = TYPE_WRITE_TO; self->handle = handle; From 2243f0b4cf5a76a6cd48ac4b5ba6bf8d6ea14be3 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Sun, 13 Mar 2022 19:16:48 +0200 Subject: [PATCH 2/5] Run CancelIOEx with GIL released --- Modules/overlapped.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/overlapped.c b/Modules/overlapped.c index e6e991dd6df1d6..e36865303b0cf2 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -707,10 +707,10 @@ Overlapped_dealloc(OverlappedObject *self) if (!HasOverlappedIoCompleted(&self->overlapped) && self->type != TYPE_NOT_STARTED) { + Py_BEGIN_ALLOW_THREADS if (CancelIoEx(self->handle, &self->overlapped)) wait = TRUE; - Py_BEGIN_ALLOW_THREADS ret = GetOverlappedResult(self->handle, &self->overlapped, &bytes, wait); Py_END_ALLOW_THREADS From 357df44fcef6df98497eb7178183e01775eb3209 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Sun, 13 Mar 2022 19:30:11 +0200 Subject: [PATCH 3/5] Fix compiler errors --- Modules/overlapped.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/Modules/overlapped.c b/Modules/overlapped.c index e36865303b0cf2..cdf52ecc6f3beb 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -79,7 +79,7 @@ typedef struct { /* Buffer allocated by us: TYPE_READ and TYPE_ACCEPT */ PyObject *allocated_buffer; /* Buffer passed by the user: TYPE_WRITE, TYPE_WRITE_TO, and TYPE_READINTO */ - Py_buffer user_buffer; + Py_buffer *user_buffer; /* Data used for reading from a connectionless socket: TYPE_READ_FROM */ @@ -163,7 +163,6 @@ initialize_function_pointers(void) GUID GuidConnectEx = WSAID_CONNECTEX; GUID GuidDisconnectEx = WSAID_DISCONNECTEX; GUID GuidTransmitFile = WSAID_TRANSMITFILE; - HINSTANCE hKernel32; SOCKET s; DWORD dwBytes; @@ -645,7 +644,7 @@ _overlapped_Overlapped_impl(PyTypeObject *type, HANDLE event) self->type = TYPE_NONE; self->allocated_buffer = NULL; memset(&self->overlapped, 0, sizeof(OVERLAPPED)); - memset(&self->user_buffer, 0, sizeof(Py_buffer)); + memset(self->user_buffer, 0, sizeof(Py_buffer)); if (event) self->overlapped.hEvent = event; return (PyObject *)self; @@ -686,8 +685,8 @@ Overlapped_clear(OverlappedObject *self) case TYPE_WRITE: case TYPE_WRITE_TO: case TYPE_READINTO: { - if (self->user_buffer.obj) { - PyBuffer_Release(&self->user_buffer); + if (self->user_buffer->obj) { + PyBuffer_Release(self->user_buffer); } break; } @@ -1061,8 +1060,8 @@ _overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, self->type = TYPE_READINTO; self->handle = handle; - return do_ReadFile(self, handle, self->user_buffer.buf, - (DWORD)self->user_buffer.len); + return do_ReadFile(self, handle, self->user_buffer->buf, + (DWORD)self->user_buffer->len); } static PyObject * @@ -1168,8 +1167,8 @@ _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, self->type = TYPE_READINTO; self->handle = handle; - return do_WSARecv(self, handle, self->user_buffer.buf, - (DWORD)self->user_buffer.len, flags); + return do_WSARecv(self, handle, self->user_buffer->buf, + (DWORD)self->user_buffer->len, flags); } /*[clinic input] @@ -1208,8 +1207,8 @@ _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, self->handle = handle; Py_BEGIN_ALLOW_THREADS - ret = WriteFile(handle, self->user_buffer.buf, - (DWORD)self->user_buffer.len, + ret = WriteFile(handle, self->user_buffer->buf, + (DWORD)self->user_buffer->len, &written, &self->overlapped); Py_END_ALLOW_THREADS @@ -1260,8 +1259,8 @@ _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, self->type = TYPE_WRITE; self->handle = handle; - wsabuf.len = (DWORD)self->user_buffer.len; - wsabuf.buf = self->user_buffer.buf; + wsabuf.len = (DWORD)self->user_buffer->len; + wsabuf.buf = self->user_buffer->buf; Py_BEGIN_ALLOW_THREADS ret = WSASend((SOCKET)handle, &wsabuf, 1, &written, flags, @@ -1646,8 +1645,8 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) case TYPE_WRITE: case TYPE_WRITE_TO: case TYPE_READINTO: - if (self->user_buffer.obj) { - Py_VISIT(&self->user_buffer.obj); + if (self->user_buffer->obj) { + Py_VISIT(&self->user_buffer->obj); } break; case TYPE_READ_FROM: @@ -1760,8 +1759,8 @@ _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, self->type = TYPE_WRITE_TO; self->handle = handle; - wsabuf.len = (DWORD)self->user_buffer.len; - wsabuf.buf = self->user_buffer.buf; + wsabuf.len = (DWORD)self->user_buffer->len; + wsabuf.buf = self->user_buffer->buf; Py_BEGIN_ALLOW_THREADS ret = WSASendTo((SOCKET)handle, &wsabuf, 1, &written, flags, From 720fd84e2151abff16d3cb8595e758950346b3f5 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Sun, 13 Mar 2022 20:21:17 +0200 Subject: [PATCH 4/5] Fix memory management --- Modules/overlapped.c | 60 ++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/Modules/overlapped.c b/Modules/overlapped.c index cdf52ecc6f3beb..a8747eb478469c 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -79,7 +79,7 @@ typedef struct { /* Buffer allocated by us: TYPE_READ and TYPE_ACCEPT */ PyObject *allocated_buffer; /* Buffer passed by the user: TYPE_WRITE, TYPE_WRITE_TO, and TYPE_READINTO */ - Py_buffer *user_buffer; + Py_buffer user_buffer; /* Data used for reading from a connectionless socket: TYPE_READ_FROM */ @@ -98,7 +98,7 @@ typedef struct { // A (number of bytes read, (host, port)) tuple PyObject* result; /* Buffer passed by the user */ - Py_buffer *user_buffer; + Py_buffer user_buffer; struct sockaddr_in6 address; int address_length; } read_from_into; @@ -118,6 +118,13 @@ overlapped_get_state(PyObject *module) } +static inline void +steal_buffer(Py_buffer * dst, Py_buffer * src) +{ + memcpy(dst, src, sizeof(Py_buffer)); + memset(src, 0, sizeof(Py_buffer)); +} + /* * Map Windows error codes to subclasses of OSError */ @@ -644,7 +651,7 @@ _overlapped_Overlapped_impl(PyTypeObject *type, HANDLE event) self->type = TYPE_NONE; self->allocated_buffer = NULL; memset(&self->overlapped, 0, sizeof(OVERLAPPED)); - memset(self->user_buffer, 0, sizeof(Py_buffer)); + memset(&self->user_buffer, 0, sizeof(Py_buffer)); if (event) self->overlapped.hEvent = event; return (PyObject *)self; @@ -680,13 +687,16 @@ Overlapped_clear(OverlappedObject *self) // We've received a message, free the result tuple. Py_CLEAR(self->read_from_into.result); } + if (self->read_from_into->user_buffer.obj) { + PyBuffer_Release(&self->read_from_into->user_buffer); + } break; } case TYPE_WRITE: case TYPE_WRITE_TO: case TYPE_READINTO: { - if (self->user_buffer->obj) { - PyBuffer_Release(self->user_buffer); + if (self->user_buffer.obj) { + PyBuffer_Release(&self->user_buffer); } break; } @@ -1055,13 +1065,13 @@ _overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, return NULL; } #endif - self->user_buffer = bufobj; + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_READINTO; self->handle = handle; - return do_ReadFile(self, handle, self->user_buffer->buf, - (DWORD)self->user_buffer->len); + return do_ReadFile(self, handle, self->user_buffer.buf, + (DWORD)self->user_buffer.len); } static PyObject * @@ -1162,13 +1172,13 @@ _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, return NULL; } #endif - self->user_buffer = bufobj; + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_READINTO; self->handle = handle; - return do_WSARecv(self, handle, self->user_buffer->buf, - (DWORD)self->user_buffer->len, flags); + return do_WSARecv(self, handle, self->user_buffer.buf, + (DWORD)self->user_buffer.len, flags); } /*[clinic input] @@ -1201,14 +1211,14 @@ _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, return NULL; } #endif - self->user_buffer = bufobj; + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_WRITE; self->handle = handle; Py_BEGIN_ALLOW_THREADS - ret = WriteFile(handle, self->user_buffer->buf, - (DWORD)self->user_buffer->len, + ret = WriteFile(handle, self->user_buffer.buf, + (DWORD)self->user_buffer.len, &written, &self->overlapped); Py_END_ALLOW_THREADS @@ -1255,12 +1265,12 @@ _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, return NULL; } #endif - self->user_buffer = bufobj; + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_WRITE; self->handle = handle; - wsabuf.len = (DWORD)self->user_buffer->len; - wsabuf.buf = self->user_buffer->buf; + wsabuf.len = (DWORD)self->user_buffer.len; + wsabuf.buf = self->user_buffer.buf; Py_BEGIN_ALLOW_THREADS ret = WSASend((SOCKET)handle, &wsabuf, 1, &written, flags, @@ -1645,8 +1655,8 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) case TYPE_WRITE: case TYPE_WRITE_TO: case TYPE_READINTO: - if (self->user_buffer->obj) { - Py_VISIT(&self->user_buffer->obj); + if (self->user_buffer.obj) { + Py_VISIT(&self->user_buffer.obj); } break; case TYPE_READ_FROM: @@ -1655,8 +1665,8 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) break; case TYPE_READ_FROM_INTO: Py_VISIT(self->read_from_into.result); - if (self->read_from_into.user_buffer->obj) { - Py_VISIT(&self->read_from_into.user_buffer->obj); + if (self->read_from_into.user_buffer.obj) { + Py_VISIT(&self->read_from_into.user_buffer.obj); } break; } @@ -1755,12 +1765,12 @@ _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, return NULL; } #endif - self->user_buffer = bufobj; + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_WRITE_TO; self->handle = handle; - wsabuf.len = (DWORD)self->user_buffer->len; - wsabuf.buf = self->user_buffer->buf; + wsabuf.len = (DWORD)self->user_buffer.len; + wsabuf.buf = self->user_buffer.buf; Py_BEGIN_ALLOW_THREADS ret = WSASendTo((SOCKET)handle, &wsabuf, 1, &written, flags, @@ -1895,7 +1905,7 @@ _overlapped_Overlapped_WSARecvFromInto_impl(OverlappedObject *self, self->type = TYPE_READ_FROM_INTO; self->handle = handle; - self->read_from_into.user_buffer = bufobj; + steal_buffer(&self->read_from_into.user_buffer, bufobj); memset(&self->read_from_into.address, 0, sizeof(self->read_from_into.address)); self->read_from_into.address_length = sizeof(self->read_from_into.address); From 50b1380744dc8c45d5e0a707aff16d30b5b5c30b Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Sun, 13 Mar 2022 20:28:56 +0200 Subject: [PATCH 5/5] Fix compile error --- Modules/overlapped.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/overlapped.c b/Modules/overlapped.c index a8747eb478469c..74fba8346c2e1c 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -687,8 +687,8 @@ Overlapped_clear(OverlappedObject *self) // We've received a message, free the result tuple. Py_CLEAR(self->read_from_into.result); } - if (self->read_from_into->user_buffer.obj) { - PyBuffer_Release(&self->read_from_into->user_buffer); + if (self->read_from_into.user_buffer.obj) { + PyBuffer_Release(&self->read_from_into.user_buffer); } break; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy