Skip to content

Commit 720fd84

Browse files
committed
Fix memory management
1 parent 357df44 commit 720fd84

File tree

1 file changed

+35
-25
lines changed

1 file changed

+35
-25
lines changed

Modules/overlapped.c

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ typedef struct {
7979
/* Buffer allocated by us: TYPE_READ and TYPE_ACCEPT */
8080
PyObject *allocated_buffer;
8181
/* Buffer passed by the user: TYPE_WRITE, TYPE_WRITE_TO, and TYPE_READINTO */
82-
Py_buffer *user_buffer;
82+
Py_buffer user_buffer;
8383

8484
/* Data used for reading from a connectionless socket:
8585
TYPE_READ_FROM */
@@ -98,7 +98,7 @@ typedef struct {
9898
// A (number of bytes read, (host, port)) tuple
9999
PyObject* result;
100100
/* Buffer passed by the user */
101-
Py_buffer *user_buffer;
101+
Py_buffer user_buffer;
102102
struct sockaddr_in6 address;
103103
int address_length;
104104
} read_from_into;
@@ -118,6 +118,13 @@ overlapped_get_state(PyObject *module)
118118
}
119119

120120

121+
static inline void
122+
steal_buffer(Py_buffer * dst, Py_buffer * src)
123+
{
124+
memcpy(dst, src, sizeof(Py_buffer));
125+
memset(src, 0, sizeof(Py_buffer));
126+
}
127+
121128
/*
122129
* Map Windows error codes to subclasses of OSError
123130
*/
@@ -644,7 +651,7 @@ _overlapped_Overlapped_impl(PyTypeObject *type, HANDLE event)
644651
self->type = TYPE_NONE;
645652
self->allocated_buffer = NULL;
646653
memset(&self->overlapped, 0, sizeof(OVERLAPPED));
647-
memset(self->user_buffer, 0, sizeof(Py_buffer));
654+
memset(&self->user_buffer, 0, sizeof(Py_buffer));
648655
if (event)
649656
self->overlapped.hEvent = event;
650657
return (PyObject *)self;
@@ -680,13 +687,16 @@ Overlapped_clear(OverlappedObject *self)
680687
// We've received a message, free the result tuple.
681688
Py_CLEAR(self->read_from_into.result);
682689
}
690+
if (self->read_from_into->user_buffer.obj) {
691+
PyBuffer_Release(&self->read_from_into->user_buffer);
692+
}
683693
break;
684694
}
685695
case TYPE_WRITE:
686696
case TYPE_WRITE_TO:
687697
case TYPE_READINTO: {
688-
if (self->user_buffer->obj) {
689-
PyBuffer_Release(self->user_buffer);
698+
if (self->user_buffer.obj) {
699+
PyBuffer_Release(&self->user_buffer);
690700
}
691701
break;
692702
}
@@ -1055,13 +1065,13 @@ _overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self,
10551065
return NULL;
10561066
}
10571067
#endif
1058-
self->user_buffer = bufobj;
1068+
steal_buffer(&self->user_buffer, bufobj);
10591069

10601070
self->type = TYPE_READINTO;
10611071
self->handle = handle;
10621072

1063-
return do_ReadFile(self, handle, self->user_buffer->buf,
1064-
(DWORD)self->user_buffer->len);
1073+
return do_ReadFile(self, handle, self->user_buffer.buf,
1074+
(DWORD)self->user_buffer.len);
10651075
}
10661076

10671077
static PyObject *
@@ -1162,13 +1172,13 @@ _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self,
11621172
return NULL;
11631173
}
11641174
#endif
1165-
self->user_buffer = bufobj;
1175+
steal_buffer(&self->user_buffer, bufobj);
11661176

11671177
self->type = TYPE_READINTO;
11681178
self->handle = handle;
11691179

1170-
return do_WSARecv(self, handle, self->user_buffer->buf,
1171-
(DWORD)self->user_buffer->len, flags);
1180+
return do_WSARecv(self, handle, self->user_buffer.buf,
1181+
(DWORD)self->user_buffer.len, flags);
11721182
}
11731183

11741184
/*[clinic input]
@@ -1201,14 +1211,14 @@ _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle,
12011211
return NULL;
12021212
}
12031213
#endif
1204-
self->user_buffer = bufobj;
1214+
steal_buffer(&self->user_buffer, bufobj);
12051215

12061216
self->type = TYPE_WRITE;
12071217
self->handle = handle;
12081218

12091219
Py_BEGIN_ALLOW_THREADS
1210-
ret = WriteFile(handle, self->user_buffer->buf,
1211-
(DWORD)self->user_buffer->len,
1220+
ret = WriteFile(handle, self->user_buffer.buf,
1221+
(DWORD)self->user_buffer.len,
12121222
&written, &self->overlapped);
12131223
Py_END_ALLOW_THREADS
12141224

@@ -1255,12 +1265,12 @@ _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle,
12551265
return NULL;
12561266
}
12571267
#endif
1258-
self->user_buffer = bufobj;
1268+
steal_buffer(&self->user_buffer, bufobj);
12591269

12601270
self->type = TYPE_WRITE;
12611271
self->handle = handle;
1262-
wsabuf.len = (DWORD)self->user_buffer->len;
1263-
wsabuf.buf = self->user_buffer->buf;
1272+
wsabuf.len = (DWORD)self->user_buffer.len;
1273+
wsabuf.buf = self->user_buffer.buf;
12641274

12651275
Py_BEGIN_ALLOW_THREADS
12661276
ret = WSASend((SOCKET)handle, &wsabuf, 1, &written, flags,
@@ -1645,8 +1655,8 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg)
16451655
case TYPE_WRITE:
16461656
case TYPE_WRITE_TO:
16471657
case TYPE_READINTO:
1648-
if (self->user_buffer->obj) {
1649-
Py_VISIT(&self->user_buffer->obj);
1658+
if (self->user_buffer.obj) {
1659+
Py_VISIT(&self->user_buffer.obj);
16501660
}
16511661
break;
16521662
case TYPE_READ_FROM:
@@ -1655,8 +1665,8 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg)
16551665
break;
16561666
case TYPE_READ_FROM_INTO:
16571667
Py_VISIT(self->read_from_into.result);
1658-
if (self->read_from_into.user_buffer->obj) {
1659-
Py_VISIT(&self->read_from_into.user_buffer->obj);
1668+
if (self->read_from_into.user_buffer.obj) {
1669+
Py_VISIT(&self->read_from_into.user_buffer.obj);
16601670
}
16611671
break;
16621672
}
@@ -1755,12 +1765,12 @@ _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle,
17551765
return NULL;
17561766
}
17571767
#endif
1758-
self->user_buffer = bufobj;
1768+
steal_buffer(&self->user_buffer, bufobj);
17591769

17601770
self->type = TYPE_WRITE_TO;
17611771
self->handle = handle;
1762-
wsabuf.len = (DWORD)self->user_buffer->len;
1763-
wsabuf.buf = self->user_buffer->buf;
1772+
wsabuf.len = (DWORD)self->user_buffer.len;
1773+
wsabuf.buf = self->user_buffer.buf;
17641774

17651775
Py_BEGIN_ALLOW_THREADS
17661776
ret = WSASendTo((SOCKET)handle, &wsabuf, 1, &written, flags,
@@ -1895,7 +1905,7 @@ _overlapped_Overlapped_WSARecvFromInto_impl(OverlappedObject *self,
18951905

18961906
self->type = TYPE_READ_FROM_INTO;
18971907
self->handle = handle;
1898-
self->read_from_into.user_buffer = bufobj;
1908+
steal_buffer(&self->read_from_into.user_buffer, bufobj);
18991909
memset(&self->read_from_into.address, 0, sizeof(self->read_from_into.address));
19001910
self->read_from_into.address_length = sizeof(self->read_from_into.address);
19011911

0 commit comments

Comments
 (0)