bpo-1635741: Port _winapi ext to multi-stage init (GH-21371)
This commit is contained in:
parent
c51db0ea40
commit
e087f7cd43
|
@ -0,0 +1 @@
|
||||||
|
Port :mod:`winapi` to multiphase initialization
|
|
@ -35,8 +35,10 @@
|
||||||
/* See http://www.python.org/2.4/license for licensing details. */
|
/* See http://www.python.org/2.4/license for licensing details. */
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
#include "moduleobject.h" // PyModuleDef_Slot
|
||||||
#include "structmember.h" // PyMemberDef
|
#include "structmember.h" // PyMemberDef
|
||||||
|
|
||||||
|
|
||||||
#define WINDOWS_LEAN_AND_MEAN
|
#define WINDOWS_LEAN_AND_MEAN
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include <crtdbg.h>
|
#include <crtdbg.h>
|
||||||
|
@ -78,6 +80,17 @@ check_CancelIoEx()
|
||||||
return has_CancelIoEx;
|
return has_CancelIoEx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyTypeObject *overlapped_type;
|
||||||
|
} WinApiState;
|
||||||
|
|
||||||
|
static inline WinApiState*
|
||||||
|
winapi_get_state(PyObject *module)
|
||||||
|
{
|
||||||
|
void *state = PyModule_GetState(module);
|
||||||
|
assert(state != NULL);
|
||||||
|
return (WinApiState *)state;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A Python object wrapping an OVERLAPPED structure and other useful data
|
* A Python object wrapping an OVERLAPPED structure and other useful data
|
||||||
|
@ -140,7 +153,9 @@ overlapped_dealloc(OverlappedObject *self)
|
||||||
if (self->write_buffer.obj)
|
if (self->write_buffer.obj)
|
||||||
PyBuffer_Release(&self->write_buffer);
|
PyBuffer_Release(&self->write_buffer);
|
||||||
Py_CLEAR(self->read_buffer);
|
Py_CLEAR(self->read_buffer);
|
||||||
PyObject_Del(self);
|
PyTypeObject *tp = Py_TYPE(self);
|
||||||
|
tp->tp_free(self);
|
||||||
|
Py_DECREF(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
|
@ -305,55 +320,29 @@ static PyMemberDef overlapped_members[] = {
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
PyTypeObject OverlappedType = {
|
static PyType_Slot winapi_overlapped_type_slots[] = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
{Py_tp_dealloc, overlapped_dealloc},
|
||||||
/* tp_name */ "_winapi.Overlapped",
|
{Py_tp_doc, "OVERLAPPED structure wrapper"},
|
||||||
/* tp_basicsize */ sizeof(OverlappedObject),
|
{Py_tp_methods, overlapped_methods},
|
||||||
/* tp_itemsize */ 0,
|
{Py_tp_members, overlapped_members},
|
||||||
/* tp_dealloc */ (destructor) overlapped_dealloc,
|
{0,0}
|
||||||
/* tp_vectorcall_offset */ 0,
|
};
|
||||||
/* tp_getattr */ 0,
|
|
||||||
/* tp_setattr */ 0,
|
static PyType_Spec winapi_overlapped_type_spec = {
|
||||||
/* tp_as_async */ 0,
|
.name = "_winapi.Overlapped",
|
||||||
/* tp_repr */ 0,
|
.basicsize = sizeof(OverlappedObject),
|
||||||
/* tp_as_number */ 0,
|
.flags = Py_TPFLAGS_DEFAULT,
|
||||||
/* tp_as_sequence */ 0,
|
.slots = winapi_overlapped_type_slots,
|
||||||
/* tp_as_mapping */ 0,
|
|
||||||
/* tp_hash */ 0,
|
|
||||||
/* tp_call */ 0,
|
|
||||||
/* tp_str */ 0,
|
|
||||||
/* tp_getattro */ 0,
|
|
||||||
/* tp_setattro */ 0,
|
|
||||||
/* tp_as_buffer */ 0,
|
|
||||||
/* tp_flags */ Py_TPFLAGS_DEFAULT,
|
|
||||||
/* tp_doc */ "OVERLAPPED structure wrapper",
|
|
||||||
/* tp_traverse */ 0,
|
|
||||||
/* tp_clear */ 0,
|
|
||||||
/* tp_richcompare */ 0,
|
|
||||||
/* tp_weaklistoffset */ 0,
|
|
||||||
/* tp_iter */ 0,
|
|
||||||
/* tp_iternext */ 0,
|
|
||||||
/* tp_methods */ overlapped_methods,
|
|
||||||
/* tp_members */ overlapped_members,
|
|
||||||
/* tp_getset */ 0,
|
|
||||||
/* tp_base */ 0,
|
|
||||||
/* tp_dict */ 0,
|
|
||||||
/* tp_descr_get */ 0,
|
|
||||||
/* tp_descr_set */ 0,
|
|
||||||
/* tp_dictoffset */ 0,
|
|
||||||
/* tp_init */ 0,
|
|
||||||
/* tp_alloc */ 0,
|
|
||||||
/* tp_new */ 0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static OverlappedObject *
|
static OverlappedObject *
|
||||||
new_overlapped(HANDLE handle)
|
new_overlapped(PyObject *module, HANDLE handle)
|
||||||
{
|
{
|
||||||
OverlappedObject *self;
|
WinApiState *st = winapi_get_state(module);
|
||||||
|
OverlappedObject *self = PyObject_New(OverlappedObject, st->overlapped_type);
|
||||||
self = PyObject_New(OverlappedObject, &OverlappedType);
|
|
||||||
if (!self)
|
if (!self)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
self->handle = handle;
|
self->handle = handle;
|
||||||
self->read_buffer = NULL;
|
self->read_buffer = NULL;
|
||||||
self->pending = 0;
|
self->pending = 0;
|
||||||
|
@ -409,7 +398,7 @@ _winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle,
|
||||||
OverlappedObject *overlapped = NULL;
|
OverlappedObject *overlapped = NULL;
|
||||||
|
|
||||||
if (use_overlapped) {
|
if (use_overlapped) {
|
||||||
overlapped = new_overlapped(handle);
|
overlapped = new_overlapped(module, handle);
|
||||||
if (!overlapped)
|
if (!overlapped)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1527,7 +1516,7 @@ _winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size,
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (use_overlapped) {
|
if (use_overlapped) {
|
||||||
overlapped = new_overlapped(handle);
|
overlapped = new_overlapped(module, handle);
|
||||||
if (!overlapped) {
|
if (!overlapped) {
|
||||||
Py_DECREF(buf);
|
Py_DECREF(buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1810,7 +1799,7 @@ _winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer,
|
||||||
OverlappedObject *overlapped = NULL;
|
OverlappedObject *overlapped = NULL;
|
||||||
|
|
||||||
if (use_overlapped) {
|
if (use_overlapped) {
|
||||||
overlapped = new_overlapped(handle);
|
overlapped = new_overlapped(module, handle);
|
||||||
if (!overlapped)
|
if (!overlapped)
|
||||||
return NULL;
|
return NULL;
|
||||||
buf = &overlapped->write_buffer;
|
buf = &overlapped->write_buffer;
|
||||||
|
@ -1921,36 +1910,33 @@ static PyMethodDef winapi_functions[] = {
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct PyModuleDef winapi_module = {
|
|
||||||
PyModuleDef_HEAD_INIT,
|
|
||||||
"_winapi",
|
|
||||||
NULL,
|
|
||||||
-1,
|
|
||||||
winapi_functions,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
#define WINAPI_CONSTANT(fmt, con) \
|
#define WINAPI_CONSTANT(fmt, con) \
|
||||||
PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con))
|
do { \
|
||||||
|
PyObject *value = Py_BuildValue(fmt, con); \
|
||||||
|
if (value == NULL) { \
|
||||||
|
return -1; \
|
||||||
|
} \
|
||||||
|
if (PyDict_SetItemString(d, #con, value) < 0) { \
|
||||||
|
Py_DECREF(value); \
|
||||||
|
return -1; \
|
||||||
|
} \
|
||||||
|
Py_DECREF(value); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
PyMODINIT_FUNC
|
static int winapi_exec(PyObject *m)
|
||||||
PyInit__winapi(void)
|
|
||||||
{
|
{
|
||||||
PyObject *d;
|
WinApiState *st = winapi_get_state(m);
|
||||||
PyObject *m;
|
|
||||||
|
|
||||||
if (PyType_Ready(&OverlappedType) < 0)
|
st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec(m, &winapi_overlapped_type_spec, NULL);
|
||||||
return NULL;
|
if (st->overlapped_type == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
m = PyModule_Create(&winapi_module);
|
if (PyModule_AddType(m, st->overlapped_type) < 0) {
|
||||||
if (m == NULL)
|
return -1;
|
||||||
return NULL;
|
}
|
||||||
d = PyModule_GetDict(m);
|
|
||||||
|
|
||||||
PyDict_SetItemString(d, "Overlapped", (PyObject *) &OverlappedType);
|
PyObject *d = PyModule_GetDict(m);
|
||||||
|
|
||||||
/* constants */
|
/* constants */
|
||||||
WINAPI_CONSTANT(F_DWORD, CREATE_NEW_CONSOLE);
|
WINAPI_CONSTANT(F_DWORD, CREATE_NEW_CONSOLE);
|
||||||
|
@ -2049,5 +2035,24 @@ PyInit__winapi(void)
|
||||||
|
|
||||||
WINAPI_CONSTANT("i", NULL);
|
WINAPI_CONSTANT("i", NULL);
|
||||||
|
|
||||||
return m;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyModuleDef_Slot winapi_slots[] = {
|
||||||
|
{Py_mod_exec, winapi_exec},
|
||||||
|
{0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct PyModuleDef winapi_module = {
|
||||||
|
PyModuleDef_HEAD_INIT,
|
||||||
|
.m_name = "_winapi",
|
||||||
|
.m_size = sizeof(WinApiState),
|
||||||
|
.m_methods = winapi_functions,
|
||||||
|
.m_slots = winapi_slots,
|
||||||
|
};
|
||||||
|
|
||||||
|
PyMODINIT_FUNC
|
||||||
|
PyInit__winapi(void)
|
||||||
|
{
|
||||||
|
return PyModuleDef_Init(&winapi_module);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue