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;
}
static PyObject *
_overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self,
- HANDLE handle, PyObject *bufobj,
+ HANDLE handle, Py_buffer *bufobj,
DWORD flags);
static PyObject *
{
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;
}
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;
}
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;
}
static PyObject *
_overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle,
- PyObject *bufobj, DWORD flags,
+ Py_buffer *bufobj, DWORD flags,
PyObject *AddressObj);
static PyObject *
{
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;
}
return return_value;
}
-/*[clinic end generated code: output=5c9b17890ef29d52 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=d19a061ea7398d23 input=a9049054013a1b77]*/
// 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;
}
+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
*/
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, \
GUID GuidConnectEx = WSAID_CONNECTEX;
GUID GuidDisconnectEx = WSAID_DISCONNECTEX;
GUID GuidTransmitFile = WSAID_TRANSMITFILE;
- HINSTANCE hKernel32;
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());
}
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;
}
* Mark operation as completed - used when reading produces ERROR_BROKEN_PIPE
*/
-static void
+static inline void
mark_as_completed(OVERLAPPED *ov)
{
ov->Internal = 0;
// 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:
if (!HasOverlappedIoCompleted(&self->overlapped) &&
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;
- Py_BEGIN_ALLOW_THREADS
ret = GetOverlappedResult(self->handle, &self->overlapped,
&bytes, wait);
Py_END_ALLOW_THREADS
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
}
_overlapped.Overlapped.ReadFileInto
handle: HANDLE
- buf as bufobj: object
+ buf as bufobj: Py_buffer
/
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
+ steal_buffer(&self->user_buffer, bufobj);
self->type = TYPE_READINTO;
self->handle = handle;
_overlapped.Overlapped.WSARecvInto
handle: HANDLE
- buf as bufobj: object
+ buf as bufobj: Py_buffer
flags: DWORD
/
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
+ steal_buffer(&self->user_buffer, bufobj);
self->type = TYPE_READINTO;
self->handle = handle;
_overlapped.Overlapped.WriteFile
handle: HANDLE
- buf as bufobj: object
+ buf as bufobj: Py_buffer
/
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;
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
+ steal_buffer(&self->user_buffer, bufobj);
self->type = TYPE_WRITE;
self->handle = handle;
_overlapped.Overlapped.WSASend
handle: HANDLE
- buf as bufobj: object
+ buf as bufobj: Py_buffer
flags: DWORD
/
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;
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
+ steal_buffer(&self->user_buffer, bufobj);
self->type = TYPE_WRITE;
self->handle = handle;
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;
}
_overlapped.Overlapped.WSASendTo
handle: HANDLE
- buf as bufobj: object
+ buf as bufobj: Py_buffer
flags: DWORD
address_as_bytes as AddressObj: object
/
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;
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
+ steal_buffer(&self->user_buffer, bufobj);
self->type = TYPE_WRITE_TO;
self->handle = handle;
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);