summaryrefslogtreecommitdiffstats
path: root/Modules/_winapi.c
diff options
context:
space:
mode:
authorMohamed Koubaa <koubaa.m@gmail.com>2020-08-13 14:22:48 (GMT)
committerGitHub <noreply@github.com>2020-08-13 14:22:48 (GMT)
commite087f7cd43dfa4223c55a8ecd71f4a7d685178e4 (patch)
tree3a472e8949cd99bb9326d53bfe2263df6fe65881 /Modules/_winapi.c
parentc51db0ea40ddabaf5f771ea633b37fcf4c90a495 (diff)
downloadcpython-e087f7cd43dfa4223c55a8ecd71f4a7d685178e4.zip
cpython-e087f7cd43dfa4223c55a8ecd71f4a7d685178e4.tar.gz
cpython-e087f7cd43dfa4223c55a8ecd71f4a7d685178e4.tar.bz2
bpo-1635741: Port _winapi ext to multi-stage init (GH-21371)
Diffstat (limited to 'Modules/_winapi.c')
-rw-r--r--Modules/_winapi.c151
1 files changed, 78 insertions, 73 deletions
diff --git a/Modules/_winapi.c b/Modules/_winapi.c
index ddb11aa..7ba1409 100644
--- a/Modules/_winapi.c
+++ b/Modules/_winapi.c
@@ -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))
-
-PyMODINIT_FUNC
-PyInit__winapi(void)
+ 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)
+
+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);
}