Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e087f7c

Browse filesBrowse files
authored
bpo-1635741: Port _winapi ext to multi-stage init (GH-21371)
1 parent c51db0e commit e087f7c
Copy full SHA for e087f7c

File tree

2 files changed

+79
-73
lines changed
Filter options

2 files changed

+79
-73
lines changed
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Port :mod:`winapi` to multiphase initialization

‎Modules/_winapi.c

Copy file name to clipboardExpand all lines: Modules/_winapi.c
+78-73Lines changed: 78 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@
3535
/* See http://www.python.org/2.4/license for licensing details. */
3636

3737
#include "Python.h"
38+
#include "moduleobject.h" // PyModuleDef_Slot
3839
#include "structmember.h" // PyMemberDef
3940

41+
4042
#define WINDOWS_LEAN_AND_MEAN
4143
#include "windows.h"
4244
#include <crtdbg.h>
@@ -78,6 +80,17 @@ check_CancelIoEx()
7880
return has_CancelIoEx;
7981
}
8082

83+
typedef struct {
84+
PyTypeObject *overlapped_type;
85+
} WinApiState;
86+
87+
static inline WinApiState*
88+
winapi_get_state(PyObject *module)
89+
{
90+
void *state = PyModule_GetState(module);
91+
assert(state != NULL);
92+
return (WinApiState *)state;
93+
}
8194

8295
/*
8396
* A Python object wrapping an OVERLAPPED structure and other useful data
@@ -140,7 +153,9 @@ overlapped_dealloc(OverlappedObject *self)
140153
if (self->write_buffer.obj)
141154
PyBuffer_Release(&self->write_buffer);
142155
Py_CLEAR(self->read_buffer);
143-
PyObject_Del(self);
156+
PyTypeObject *tp = Py_TYPE(self);
157+
tp->tp_free(self);
158+
Py_DECREF(tp);
144159
}
145160

146161
/*[clinic input]
@@ -305,55 +320,29 @@ static PyMemberDef overlapped_members[] = {
305320
{NULL}
306321
};
307322

308-
PyTypeObject OverlappedType = {
309-
PyVarObject_HEAD_INIT(NULL, 0)
310-
/* tp_name */ "_winapi.Overlapped",
311-
/* tp_basicsize */ sizeof(OverlappedObject),
312-
/* tp_itemsize */ 0,
313-
/* tp_dealloc */ (destructor) overlapped_dealloc,
314-
/* tp_vectorcall_offset */ 0,
315-
/* tp_getattr */ 0,
316-
/* tp_setattr */ 0,
317-
/* tp_as_async */ 0,
318-
/* tp_repr */ 0,
319-
/* tp_as_number */ 0,
320-
/* tp_as_sequence */ 0,
321-
/* tp_as_mapping */ 0,
322-
/* tp_hash */ 0,
323-
/* tp_call */ 0,
324-
/* tp_str */ 0,
325-
/* tp_getattro */ 0,
326-
/* tp_setattro */ 0,
327-
/* tp_as_buffer */ 0,
328-
/* tp_flags */ Py_TPFLAGS_DEFAULT,
329-
/* tp_doc */ "OVERLAPPED structure wrapper",
330-
/* tp_traverse */ 0,
331-
/* tp_clear */ 0,
332-
/* tp_richcompare */ 0,
333-
/* tp_weaklistoffset */ 0,
334-
/* tp_iter */ 0,
335-
/* tp_iternext */ 0,
336-
/* tp_methods */ overlapped_methods,
337-
/* tp_members */ overlapped_members,
338-
/* tp_getset */ 0,
339-
/* tp_base */ 0,
340-
/* tp_dict */ 0,
341-
/* tp_descr_get */ 0,
342-
/* tp_descr_set */ 0,
343-
/* tp_dictoffset */ 0,
344-
/* tp_init */ 0,
345-
/* tp_alloc */ 0,
346-
/* tp_new */ 0,
323+
static PyType_Slot winapi_overlapped_type_slots[] = {
324+
{Py_tp_dealloc, overlapped_dealloc},
325+
{Py_tp_doc, "OVERLAPPED structure wrapper"},
326+
{Py_tp_methods, overlapped_methods},
327+
{Py_tp_members, overlapped_members},
328+
{0,0}
329+
};
330+
331+
static PyType_Spec winapi_overlapped_type_spec = {
332+
.name = "_winapi.Overlapped",
333+
.basicsize = sizeof(OverlappedObject),
334+
.flags = Py_TPFLAGS_DEFAULT,
335+
.slots = winapi_overlapped_type_slots,
347336
};
348337

349338
static OverlappedObject *
350-
new_overlapped(HANDLE handle)
339+
new_overlapped(PyObject *module, HANDLE handle)
351340
{
352-
OverlappedObject *self;
353-
354-
self = PyObject_New(OverlappedObject, &OverlappedType);
341+
WinApiState *st = winapi_get_state(module);
342+
OverlappedObject *self = PyObject_New(OverlappedObject, st->overlapped_type);
355343
if (!self)
356344
return NULL;
345+
357346
self->handle = handle;
358347
self->read_buffer = NULL;
359348
self->pending = 0;
@@ -409,7 +398,7 @@ _winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle,
409398
OverlappedObject *overlapped = NULL;
410399

411400
if (use_overlapped) {
412-
overlapped = new_overlapped(handle);
401+
overlapped = new_overlapped(module, handle);
413402
if (!overlapped)
414403
return NULL;
415404
}
@@ -1527,7 +1516,7 @@ _winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size,
15271516
if (!buf)
15281517
return NULL;
15291518
if (use_overlapped) {
1530-
overlapped = new_overlapped(handle);
1519+
overlapped = new_overlapped(module, handle);
15311520
if (!overlapped) {
15321521
Py_DECREF(buf);
15331522
return NULL;
@@ -1810,7 +1799,7 @@ _winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer,
18101799
OverlappedObject *overlapped = NULL;
18111800

18121801
if (use_overlapped) {
1813-
overlapped = new_overlapped(handle);
1802+
overlapped = new_overlapped(module, handle);
18141803
if (!overlapped)
18151804
return NULL;
18161805
buf = &overlapped->write_buffer;
@@ -1921,36 +1910,33 @@ static PyMethodDef winapi_functions[] = {
19211910
{NULL, NULL}
19221911
};
19231912

1924-
static struct PyModuleDef winapi_module = {
1925-
PyModuleDef_HEAD_INIT,
1926-
"_winapi",
1927-
NULL,
1928-
-1,
1929-
winapi_functions,
1930-
NULL,
1931-
NULL,
1932-
NULL,
1933-
NULL
1934-
};
1935-
19361913
#define WINAPI_CONSTANT(fmt, con) \
1937-
PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con))
1938-
1939-
PyMODINIT_FUNC
1940-
PyInit__winapi(void)
1914+
do { \
1915+
PyObject *value = Py_BuildValue(fmt, con); \
1916+
if (value == NULL) { \
1917+
return -1; \
1918+
} \
1919+
if (PyDict_SetItemString(d, #con, value) < 0) { \
1920+
Py_DECREF(value); \
1921+
return -1; \
1922+
} \
1923+
Py_DECREF(value); \
1924+
} while (0)
1925+
1926+
static int winapi_exec(PyObject *m)
19411927
{
1942-
PyObject *d;
1943-
PyObject *m;
1928+
WinApiState *st = winapi_get_state(m);
19441929

1945-
if (PyType_Ready(&OverlappedType) < 0)
1946-
return NULL;
1930+
st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec(m, &winapi_overlapped_type_spec, NULL);
1931+
if (st->overlapped_type == NULL) {
1932+
return -1;
1933+
}
19471934

1948-
m = PyModule_Create(&winapi_module);
1949-
if (m == NULL)
1950-
return NULL;
1951-
d = PyModule_GetDict(m);
1935+
if (PyModule_AddType(m, st->overlapped_type) < 0) {
1936+
return -1;
1937+
}
19521938

1953-
PyDict_SetItemString(d, "Overlapped", (PyObject *) &OverlappedType);
1939+
PyObject *d = PyModule_GetDict(m);
19541940

19551941
/* constants */
19561942
WINAPI_CONSTANT(F_DWORD, CREATE_NEW_CONSOLE);
@@ -2049,5 +2035,24 @@ PyInit__winapi(void)
20492035

20502036
WINAPI_CONSTANT("i", NULL);
20512037

2052-
return m;
2038+
return 0;
2039+
}
2040+
2041+
static PyModuleDef_Slot winapi_slots[] = {
2042+
{Py_mod_exec, winapi_exec},
2043+
{0, NULL}
2044+
};
2045+
2046+
static struct PyModuleDef winapi_module = {
2047+
PyModuleDef_HEAD_INIT,
2048+
.m_name = "_winapi",
2049+
.m_size = sizeof(WinApiState),
2050+
.m_methods = winapi_functions,
2051+
.m_slots = winapi_slots,
2052+
};
2053+
2054+
PyMODINIT_FUNC
2055+
PyInit__winapi(void)
2056+
{
2057+
return PyModuleDef_Init(&winapi_module);
20532058
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.