bpo-47003: Cleanup _overlapped module (GH-31848)

This commit is contained in:
Andrew Svetlov 2022-03-13 23:28:45 +02:00 committed by GitHub
parent b1e2868607
commit 690490e4de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 99 additions and 81 deletions

View file

@ -466,22 +466,27 @@ PyDoc_STRVAR(_overlapped_Overlapped_ReadFileInto__doc__,
static PyObject * static PyObject *
_overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, _overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self,
HANDLE handle, PyObject *bufobj); HANDLE handle, Py_buffer *bufobj);
static PyObject * static PyObject *
_overlapped_Overlapped_ReadFileInto(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) _overlapped_Overlapped_ReadFileInto(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
HANDLE handle; 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)) { &handle, &bufobj)) {
goto exit; goto exit;
} }
return_value = _overlapped_Overlapped_ReadFileInto_impl(self, handle, bufobj); return_value = _overlapped_Overlapped_ReadFileInto_impl(self, handle, &bufobj);
exit: exit:
/* Cleanup for bufobj */
if (bufobj.obj) {
PyBuffer_Release(&bufobj);
}
return return_value; return return_value;
} }
@ -527,7 +532,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSARecvInto__doc__,
static PyObject * static PyObject *
_overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self,
HANDLE handle, PyObject *bufobj, HANDLE handle, Py_buffer *bufobj,
DWORD flags); DWORD flags);
static PyObject * static PyObject *
@ -535,16 +540,21 @@ _overlapped_Overlapped_WSARecvInto(OverlappedObject *self, PyObject *const *args
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
HANDLE handle; HANDLE handle;
PyObject *bufobj; Py_buffer bufobj = {NULL, NULL};
DWORD flags; DWORD flags;
if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"Ok:WSARecvInto", if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*k:WSARecvInto",
&handle, &bufobj, &flags)) { &handle, &bufobj, &flags)) {
goto exit; goto exit;
} }
return_value = _overlapped_Overlapped_WSARecvInto_impl(self, handle, bufobj, flags); return_value = _overlapped_Overlapped_WSARecvInto_impl(self, handle, &bufobj, flags);
exit: exit:
/* Cleanup for bufobj */
if (bufobj.obj) {
PyBuffer_Release(&bufobj);
}
return return_value; return return_value;
} }
@ -559,22 +569,27 @@ PyDoc_STRVAR(_overlapped_Overlapped_WriteFile__doc__,
static PyObject * static PyObject *
_overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle,
PyObject *bufobj); Py_buffer *bufobj);
static PyObject * static PyObject *
_overlapped_Overlapped_WriteFile(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) _overlapped_Overlapped_WriteFile(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
HANDLE handle; 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)) { &handle, &bufobj)) {
goto exit; goto exit;
} }
return_value = _overlapped_Overlapped_WriteFile_impl(self, handle, bufobj); return_value = _overlapped_Overlapped_WriteFile_impl(self, handle, &bufobj);
exit: exit:
/* Cleanup for bufobj */
if (bufobj.obj) {
PyBuffer_Release(&bufobj);
}
return return_value; return return_value;
} }
@ -589,23 +604,28 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSASend__doc__,
static PyObject * static PyObject *
_overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle,
PyObject *bufobj, DWORD flags); Py_buffer *bufobj, DWORD flags);
static PyObject * static PyObject *
_overlapped_Overlapped_WSASend(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) _overlapped_Overlapped_WSASend(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
HANDLE handle; HANDLE handle;
PyObject *bufobj; Py_buffer bufobj = {NULL, NULL};
DWORD flags; DWORD flags;
if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"Ok:WSASend", if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*k:WSASend",
&handle, &bufobj, &flags)) { &handle, &bufobj, &flags)) {
goto exit; goto exit;
} }
return_value = _overlapped_Overlapped_WSASend_impl(self, handle, bufobj, flags); return_value = _overlapped_Overlapped_WSASend_impl(self, handle, &bufobj, flags);
exit: exit:
/* Cleanup for bufobj */
if (bufobj.obj) {
PyBuffer_Release(&bufobj);
}
return return_value; return return_value;
} }
@ -852,7 +872,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSASendTo__doc__,
static PyObject * static PyObject *
_overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle,
PyObject *bufobj, DWORD flags, Py_buffer *bufobj, DWORD flags,
PyObject *AddressObj); PyObject *AddressObj);
static PyObject * static PyObject *
@ -860,17 +880,22 @@ _overlapped_Overlapped_WSASendTo(OverlappedObject *self, PyObject *const *args,
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
HANDLE handle; HANDLE handle;
PyObject *bufobj; Py_buffer bufobj = {NULL, NULL};
DWORD flags; DWORD flags;
PyObject *AddressObj; 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)) { &handle, &bufobj, &flags, &AddressObj)) {
goto exit; 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: exit:
/* Cleanup for bufobj */
if (bufobj.obj) {
PyBuffer_Release(&bufobj);
}
return return_value; return return_value;
} }
@ -943,4 +968,4 @@ exit:
return return_value; return return_value;
} }
/*[clinic end generated code: output=5c9b17890ef29d52 input=a9049054013a1b77]*/ /*[clinic end generated code: output=d19a061ea7398d23 input=a9049054013a1b77]*/

View file

@ -98,7 +98,7 @@ typedef struct {
// A (number of bytes read, (host, port)) tuple // A (number of bytes read, (host, port)) tuple
PyObject* result; PyObject* result;
/* Buffer passed by the user */ /* Buffer passed by the user */
Py_buffer *user_buffer; Py_buffer user_buffer;
struct sockaddr_in6 address; struct sockaddr_in6 address;
int address_length; int address_length;
} read_from_into; } 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 * Map Windows error codes to subclasses of OSError
*/ */
@ -150,7 +157,6 @@ static LPFN_ACCEPTEX Py_AcceptEx = NULL;
static LPFN_CONNECTEX Py_ConnectEx = NULL; static LPFN_CONNECTEX Py_ConnectEx = NULL;
static LPFN_DISCONNECTEX Py_DisconnectEx = NULL; static LPFN_DISCONNECTEX Py_DisconnectEx = NULL;
static LPFN_TRANSMITFILE Py_TransmitFile = NULL; static LPFN_TRANSMITFILE Py_TransmitFile = NULL;
static BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED) = NULL;
#define GET_WSA_POINTER(s, x) \ #define GET_WSA_POINTER(s, x) \
(SOCKET_ERROR != WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ (SOCKET_ERROR != WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \
@ -164,10 +170,19 @@ initialize_function_pointers(void)
GUID GuidConnectEx = WSAID_CONNECTEX; GUID GuidConnectEx = WSAID_CONNECTEX;
GUID GuidDisconnectEx = WSAID_DISCONNECTEX; GUID GuidDisconnectEx = WSAID_DISCONNECTEX;
GUID GuidTransmitFile = WSAID_TRANSMITFILE; GUID GuidTransmitFile = WSAID_TRANSMITFILE;
HINSTANCE hKernel32;
SOCKET s; SOCKET s;
DWORD dwBytes; 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); s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET) { if (s == INVALID_SOCKET) {
SetFromWindowsErr(WSAGetLastError()); SetFromWindowsErr(WSAGetLastError());
@ -185,12 +200,6 @@ initialize_function_pointers(void)
} }
closesocket(s); 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; return 0;
} }
@ -596,7 +605,7 @@ _overlapped_FormatMessage_impl(PyObject *module, DWORD code)
* Mark operation as completed - used when reading produces ERROR_BROKEN_PIPE * Mark operation as completed - used when reading produces ERROR_BROKEN_PIPE
*/ */
static void static inline void
mark_as_completed(OVERLAPPED *ov) mark_as_completed(OVERLAPPED *ov)
{ {
ov->Internal = 0; ov->Internal = 0;
@ -678,6 +687,9 @@ Overlapped_clear(OverlappedObject *self)
// We've received a message, free the result tuple. // We've received a message, free the result tuple.
Py_CLEAR(self->read_from_into.result); Py_CLEAR(self->read_from_into.result);
} }
if (self->read_from_into.user_buffer.obj) {
PyBuffer_Release(&self->read_from_into.user_buffer);
}
break; break;
} }
case TYPE_WRITE: case TYPE_WRITE:
@ -704,10 +716,10 @@ Overlapped_dealloc(OverlappedObject *self)
if (!HasOverlappedIoCompleted(&self->overlapped) && if (!HasOverlappedIoCompleted(&self->overlapped) &&
self->type != TYPE_NOT_STARTED) self->type != TYPE_NOT_STARTED)
{ {
if (Py_CancelIoEx && Py_CancelIoEx(self->handle, &self->overlapped)) Py_BEGIN_ALLOW_THREADS
if (CancelIoEx(self->handle, &self->overlapped))
wait = TRUE; wait = TRUE;
Py_BEGIN_ALLOW_THREADS
ret = GetOverlappedResult(self->handle, &self->overlapped, ret = GetOverlappedResult(self->handle, &self->overlapped,
&bytes, wait); &bytes, wait);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
@ -820,10 +832,7 @@ _overlapped_Overlapped_cancel_impl(OverlappedObject *self)
if (!HasOverlappedIoCompleted(&self->overlapped)) { if (!HasOverlappedIoCompleted(&self->overlapped)) {
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
if (Py_CancelIoEx) ret = CancelIoEx(self->handle, &self->overlapped);
ret = Py_CancelIoEx(self->handle, &self->overlapped);
else
ret = CancelIo(self->handle);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
} }
@ -1034,7 +1043,7 @@ _overlapped_Overlapped_ReadFile_impl(OverlappedObject *self, HANDLE handle,
_overlapped.Overlapped.ReadFileInto _overlapped.Overlapped.ReadFileInto
handle: HANDLE handle: HANDLE
buf as bufobj: object buf as bufobj: Py_buffer
/ /
Start overlapped receive. Start overlapped receive.
@ -1042,24 +1051,21 @@ Start overlapped receive.
static PyObject * static PyObject *
_overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, _overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self,
HANDLE handle, PyObject *bufobj) HANDLE handle, Py_buffer *bufobj)
/*[clinic end generated code: output=1e9e712e742e5b2a input=16f6cc268d1d0387]*/ /*[clinic end generated code: output=8754744506023071 input=4f037ba09939e32d]*/
{ {
if (self->type != TYPE_NONE) { if (self->type != TYPE_NONE) {
PyErr_SetString(PyExc_ValueError, "operation already attempted"); PyErr_SetString(PyExc_ValueError, "operation already attempted");
return NULL; return NULL;
} }
if (!PyArg_Parse(bufobj, "y*", &self->user_buffer))
return NULL;
#if SIZEOF_SIZE_T > SIZEOF_LONG #if SIZEOF_SIZE_T > SIZEOF_LONG
if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
PyBuffer_Release(&self->user_buffer);
PyErr_SetString(PyExc_ValueError, "buffer too large"); PyErr_SetString(PyExc_ValueError, "buffer too large");
return NULL; return NULL;
} }
#endif #endif
steal_buffer(&self->user_buffer, bufobj);
self->type = TYPE_READINTO; self->type = TYPE_READINTO;
self->handle = handle; self->handle = handle;
@ -1142,7 +1148,7 @@ _overlapped_Overlapped_WSARecv_impl(OverlappedObject *self, HANDLE handle,
_overlapped.Overlapped.WSARecvInto _overlapped.Overlapped.WSARecvInto
handle: HANDLE handle: HANDLE
buf as bufobj: object buf as bufobj: Py_buffer
flags: DWORD flags: DWORD
/ /
@ -1151,25 +1157,22 @@ Start overlapped receive.
static PyObject * static PyObject *
_overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self,
HANDLE handle, PyObject *bufobj, HANDLE handle, Py_buffer *bufobj,
DWORD flags) DWORD flags)
/*[clinic end generated code: output=9a438abc436fe87c input=4f87c38fc381d525]*/ /*[clinic end generated code: output=59ae7688786cf86b input=73e7fa00db633edd]*/
{ {
if (self->type != TYPE_NONE) { if (self->type != TYPE_NONE) {
PyErr_SetString(PyExc_ValueError, "operation already attempted"); PyErr_SetString(PyExc_ValueError, "operation already attempted");
return NULL; return NULL;
} }
if (!PyArg_Parse(bufobj, "y*", &self->user_buffer))
return NULL;
#if SIZEOF_SIZE_T > SIZEOF_LONG #if SIZEOF_SIZE_T > SIZEOF_LONG
if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
PyBuffer_Release(&self->user_buffer);
PyErr_SetString(PyExc_ValueError, "buffer too large"); PyErr_SetString(PyExc_ValueError, "buffer too large");
return NULL; return NULL;
} }
#endif #endif
steal_buffer(&self->user_buffer, bufobj);
self->type = TYPE_READINTO; self->type = TYPE_READINTO;
self->handle = handle; self->handle = handle;
@ -1182,7 +1185,7 @@ _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self,
_overlapped.Overlapped.WriteFile _overlapped.Overlapped.WriteFile
handle: HANDLE handle: HANDLE
buf as bufobj: object buf as bufobj: Py_buffer
/ /
Start overlapped write. Start overlapped write.
@ -1190,8 +1193,8 @@ Start overlapped write.
static PyObject * static PyObject *
_overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle,
PyObject *bufobj) Py_buffer *bufobj)
/*[clinic end generated code: output=c376230b6120d877 input=b8d9a7608d8a1e72]*/ /*[clinic end generated code: output=fa5d5880a1bf04b1 input=ac54424c362abfc1]*/
{ {
DWORD written; DWORD written;
BOOL ret; BOOL ret;
@ -1202,16 +1205,13 @@ _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle,
return NULL; return NULL;
} }
if (!PyArg_Parse(bufobj, "y*", &self->user_buffer))
return NULL;
#if SIZEOF_SIZE_T > SIZEOF_LONG #if SIZEOF_SIZE_T > SIZEOF_LONG
if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
PyBuffer_Release(&self->user_buffer);
PyErr_SetString(PyExc_ValueError, "buffer too large"); PyErr_SetString(PyExc_ValueError, "buffer too large");
return NULL; return NULL;
} }
#endif #endif
steal_buffer(&self->user_buffer, bufobj);
self->type = TYPE_WRITE; self->type = TYPE_WRITE;
self->handle = handle; self->handle = handle;
@ -1237,7 +1237,7 @@ _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle,
_overlapped.Overlapped.WSASend _overlapped.Overlapped.WSASend
handle: HANDLE handle: HANDLE
buf as bufobj: object buf as bufobj: Py_buffer
flags: DWORD flags: DWORD
/ /
@ -1246,8 +1246,8 @@ Start overlapped send.
static PyObject * static PyObject *
_overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle,
PyObject *bufobj, DWORD flags) Py_buffer *bufobj, DWORD flags)
/*[clinic end generated code: output=316031c7467040cc input=932e7cba6d18f708]*/ /*[clinic end generated code: output=3baaa6e1f7fe229e input=c4167420ba2f93d8]*/
{ {
DWORD written; DWORD written;
WSABUF wsabuf; WSABUF wsabuf;
@ -1259,16 +1259,13 @@ _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle,
return NULL; return NULL;
} }
if (!PyArg_Parse(bufobj, "y*", &self->user_buffer))
return NULL;
#if SIZEOF_SIZE_T > SIZEOF_LONG #if SIZEOF_SIZE_T > SIZEOF_LONG
if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
PyBuffer_Release(&self->user_buffer);
PyErr_SetString(PyExc_ValueError, "buffer too large"); PyErr_SetString(PyExc_ValueError, "buffer too large");
return NULL; return NULL;
} }
#endif #endif
steal_buffer(&self->user_buffer, bufobj);
self->type = TYPE_WRITE; self->type = TYPE_WRITE;
self->handle = handle; self->handle = handle;
@ -1668,8 +1665,8 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg)
break; break;
case TYPE_READ_FROM_INTO: case TYPE_READ_FROM_INTO:
Py_VISIT(self->read_from_into.result); Py_VISIT(self->read_from_into.result);
if (self->read_from_into.user_buffer->obj) { if (self->read_from_into.user_buffer.obj) {
Py_VISIT(&self->read_from_into.user_buffer->obj); Py_VISIT(&self->read_from_into.user_buffer.obj);
} }
break; break;
} }
@ -1728,7 +1725,7 @@ _overlapped_WSAConnect_impl(PyObject *module, HANDLE ConnectSocket,
_overlapped.Overlapped.WSASendTo _overlapped.Overlapped.WSASendTo
handle: HANDLE handle: HANDLE
buf as bufobj: object buf as bufobj: Py_buffer
flags: DWORD flags: DWORD
address_as_bytes as AddressObj: object address_as_bytes as AddressObj: object
/ /
@ -1738,9 +1735,9 @@ Start overlapped sendto over a connectionless (UDP) socket.
static PyObject * static PyObject *
_overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle,
PyObject *bufobj, DWORD flags, Py_buffer *bufobj, DWORD flags,
PyObject *AddressObj) PyObject *AddressObj)
/*[clinic end generated code: output=fe0ff55eb60d65e1 input=f709e6ecebd9bc18]*/ /*[clinic end generated code: output=3cdedc4cfaeb70cd input=b7c1749a62e2e374]*/
{ {
char AddressBuf[sizeof(struct sockaddr_in6)]; char AddressBuf[sizeof(struct sockaddr_in6)];
SOCKADDR *Address = (SOCKADDR*)AddressBuf; SOCKADDR *Address = (SOCKADDR*)AddressBuf;
@ -1762,17 +1759,13 @@ _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle,
return NULL; return NULL;
} }
if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) {
return NULL;
}
#if SIZEOF_SIZE_T > SIZEOF_LONG #if SIZEOF_SIZE_T > SIZEOF_LONG
if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { if (bufobj->len > (Py_ssize_t)ULONG_MAX) {
PyBuffer_Release(&self->user_buffer);
PyErr_SetString(PyExc_ValueError, "buffer too large"); PyErr_SetString(PyExc_ValueError, "buffer too large");
return NULL; return NULL;
} }
#endif #endif
steal_buffer(&self->user_buffer, bufobj);
self->type = TYPE_WRITE_TO; self->type = TYPE_WRITE_TO;
self->handle = handle; self->handle = handle;
@ -1912,7 +1905,7 @@ _overlapped_Overlapped_WSARecvFromInto_impl(OverlappedObject *self,
self->type = TYPE_READ_FROM_INTO; self->type = TYPE_READ_FROM_INTO;
self->handle = handle; 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)); 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); self->read_from_into.address_length = sizeof(self->read_from_into.address);