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. */
|
||||
|
||||
#include "Python.h"
|
||||
#include "moduleobject.h" // PyModuleDef_Slot
|
||||
#include "structmember.h" // PyMemberDef
|
||||
|
||||
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
#include "windows.h"
|
||||
#include <crtdbg.h>
|
||||
|
@ -78,6 +80,17 @@ check_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
|
||||
|
@ -140,7 +153,9 @@ overlapped_dealloc(OverlappedObject *self)
|
|||
if (self->write_buffer.obj)
|
||||
PyBuffer_Release(&self->write_buffer);
|
||||
Py_CLEAR(self->read_buffer);
|
||||
PyObject_Del(self);
|
||||
PyTypeObject *tp = Py_TYPE(self);
|
||||
tp->tp_free(self);
|
||||
Py_DECREF(tp);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
|
@ -305,55 +320,29 @@ static PyMemberDef overlapped_members[] = {
|
|||
{NULL}
|
||||
};
|
||||
|
||||
PyTypeObject OverlappedType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
/* tp_name */ "_winapi.Overlapped",
|
||||
/* tp_basicsize */ sizeof(OverlappedObject),
|
||||
/* tp_itemsize */ 0,
|
||||
/* tp_dealloc */ (destructor) overlapped_dealloc,
|
||||
/* tp_vectorcall_offset */ 0,
|
||||
/* tp_getattr */ 0,
|
||||
/* tp_setattr */ 0,
|
||||
/* tp_as_async */ 0,
|
||||
/* tp_repr */ 0,
|
||||
/* tp_as_number */ 0,
|
||||
/* tp_as_sequence */ 0,
|
||||
/* 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 PyType_Slot winapi_overlapped_type_slots[] = {
|
||||
{Py_tp_dealloc, overlapped_dealloc},
|
||||
{Py_tp_doc, "OVERLAPPED structure wrapper"},
|
||||
{Py_tp_methods, overlapped_methods},
|
||||
{Py_tp_members, overlapped_members},
|
||||
{0,0}
|
||||
};
|
||||
|
||||
static PyType_Spec winapi_overlapped_type_spec = {
|
||||
.name = "_winapi.Overlapped",
|
||||
.basicsize = sizeof(OverlappedObject),
|
||||
.flags = Py_TPFLAGS_DEFAULT,
|
||||
.slots = winapi_overlapped_type_slots,
|
||||
};
|
||||
|
||||
static OverlappedObject *
|
||||
new_overlapped(HANDLE handle)
|
||||
new_overlapped(PyObject *module, HANDLE handle)
|
||||
{
|
||||
OverlappedObject *self;
|
||||
|
||||
self = PyObject_New(OverlappedObject, &OverlappedType);
|
||||
WinApiState *st = winapi_get_state(module);
|
||||
OverlappedObject *self = PyObject_New(OverlappedObject, st->overlapped_type);
|
||||
if (!self)
|
||||
return NULL;
|
||||
|
||||
self->handle = handle;
|
||||
self->read_buffer = NULL;
|
||||
self->pending = 0;
|
||||
|
@ -409,7 +398,7 @@ _winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle,
|
|||
OverlappedObject *overlapped = NULL;
|
||||
|
||||
if (use_overlapped) {
|
||||
overlapped = new_overlapped(handle);
|
||||
overlapped = new_overlapped(module, handle);
|
||||
if (!overlapped)
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1527,7 +1516,7 @@ _winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size,
|
|||
if (!buf)
|
||||
return NULL;
|
||||
if (use_overlapped) {
|
||||
overlapped = new_overlapped(handle);
|
||||
overlapped = new_overlapped(module, handle);
|
||||
if (!overlapped) {
|
||||
Py_DECREF(buf);
|
||||
return NULL;
|
||||
|
@ -1810,7 +1799,7 @@ _winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer,
|
|||
OverlappedObject *overlapped = NULL;
|
||||
|
||||
if (use_overlapped) {
|
||||
overlapped = new_overlapped(handle);
|
||||
overlapped = new_overlapped(module, handle);
|
||||
if (!overlapped)
|
||||
return NULL;
|
||||
buf = &overlapped->write_buffer;
|
||||
|
@ -1921,36 +1910,33 @@ static PyMethodDef winapi_functions[] = {
|
|||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static struct PyModuleDef winapi_module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_winapi",
|
||||
NULL,
|
||||
-1,
|
||||
winapi_functions,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
#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
|
||||
PyInit__winapi(void)
|
||||
static int winapi_exec(PyObject *m)
|
||||
{
|
||||
PyObject *d;
|
||||
PyObject *m;
|
||||
WinApiState *st = winapi_get_state(m);
|
||||
|
||||
if (PyType_Ready(&OverlappedType) < 0)
|
||||
return NULL;
|
||||
st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec(m, &winapi_overlapped_type_spec, NULL);
|
||||
if (st->overlapped_type == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
m = PyModule_Create(&winapi_module);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
d = PyModule_GetDict(m);
|
||||
if (PyModule_AddType(m, st->overlapped_type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyDict_SetItemString(d, "Overlapped", (PyObject *) &OverlappedType);
|
||||
PyObject *d = PyModule_GetDict(m);
|
||||
|
||||
/* constants */
|
||||
WINAPI_CONSTANT(F_DWORD, CREATE_NEW_CONSOLE);
|
||||
|
@ -2049,5 +2035,24 @@ PyInit__winapi(void)
|
|||
|
||||
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