Skip to content

Commit 2aabc32

Browse files
authored
bpo-1635741: Port _overlapped module to multi-phase init (GH-22051)
Port the _overlapped extension module to multi-phase initialization (PEP 489).
1 parent 426f2b4 commit 2aabc32

File tree

2 files changed

+108
-67
lines changed

2 files changed

+108
-67
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Port the :mod:`_overlapped` extension module to multi-phase initialization
2+
(:pep:`489`).

Modules/overlapped.c

Lines changed: 106 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,19 @@ typedef struct {
100100
};
101101
} OverlappedObject;
102102

103+
typedef struct {
104+
PyTypeObject *overlapped_type;
105+
} OverlappedState;
106+
107+
static inline OverlappedState*
108+
overlapped_get_state(PyObject *module)
109+
{
110+
void *state = PyModule_GetState(module);
111+
assert(state != NULL);
112+
return (OverlappedState *)state;
113+
}
114+
115+
103116
/*
104117
* Map Windows error codes to subclasses of OSError
105118
*/
@@ -706,8 +719,11 @@ Overlapped_dealloc(OverlappedObject *self)
706719
}
707720

708721
Overlapped_clear(self);
709-
PyObject_Del(self);
710722
SetLastError(olderr);
723+
724+
PyTypeObject *tp = Py_TYPE(self);
725+
PyObject_Del(self);
726+
Py_DECREF(tp);
711727
}
712728

713729

@@ -1846,45 +1862,22 @@ static PyGetSetDef Overlapped_getsets[] = {
18461862
{NULL},
18471863
};
18481864

1849-
PyTypeObject OverlappedType = {
1850-
PyVarObject_HEAD_INIT(NULL, 0)
1851-
/* tp_name */ "_overlapped.Overlapped",
1852-
/* tp_basicsize */ sizeof(OverlappedObject),
1853-
/* tp_itemsize */ 0,
1854-
/* tp_dealloc */ (destructor) Overlapped_dealloc,
1855-
/* tp_vectorcall_offset */ 0,
1856-
/* tp_getattr */ 0,
1857-
/* tp_setattr */ 0,
1858-
/* tp_as_async */ 0,
1859-
/* tp_repr */ 0,
1860-
/* tp_as_number */ 0,
1861-
/* tp_as_sequence */ 0,
1862-
/* tp_as_mapping */ 0,
1863-
/* tp_hash */ 0,
1864-
/* tp_call */ 0,
1865-
/* tp_str */ 0,
1866-
/* tp_getattro */ 0,
1867-
/* tp_setattro */ 0,
1868-
/* tp_as_buffer */ 0,
1869-
/* tp_flags */ Py_TPFLAGS_DEFAULT,
1870-
/* tp_doc */ _overlapped_Overlapped__doc__,
1871-
/* tp_traverse */ (traverseproc)Overlapped_traverse,
1872-
/* tp_clear */ 0,
1873-
/* tp_richcompare */ 0,
1874-
/* tp_weaklistoffset */ 0,
1875-
/* tp_iter */ 0,
1876-
/* tp_iternext */ 0,
1877-
/* tp_methods */ Overlapped_methods,
1878-
/* tp_members */ Overlapped_members,
1879-
/* tp_getset */ Overlapped_getsets,
1880-
/* tp_base */ 0,
1881-
/* tp_dict */ 0,
1882-
/* tp_descr_get */ 0,
1883-
/* tp_descr_set */ 0,
1884-
/* tp_dictoffset */ 0,
1885-
/* tp_init */ 0,
1886-
/* tp_alloc */ 0,
1887-
/* tp_new */ _overlapped_Overlapped,
1865+
static PyType_Slot overlapped_type_slots[] = {
1866+
{Py_tp_dealloc, Overlapped_dealloc},
1867+
{Py_tp_doc, (char *)_overlapped_Overlapped__doc__},
1868+
{Py_tp_traverse, Overlapped_traverse},
1869+
{Py_tp_methods, Overlapped_methods},
1870+
{Py_tp_members, Overlapped_members},
1871+
{Py_tp_getset, Overlapped_getsets},
1872+
{Py_tp_new, _overlapped_Overlapped},
1873+
{0,0}
1874+
};
1875+
1876+
static PyType_Spec overlapped_type_spec = {
1877+
.name = "_overlapped.Overlapped",
1878+
.basicsize = sizeof(OverlappedObject),
1879+
.flags = Py_TPFLAGS_DEFAULT,
1880+
.slots = overlapped_type_slots
18881881
};
18891882

18901883
static PyMethodDef overlapped_functions[] = {
@@ -1904,41 +1897,65 @@ static PyMethodDef overlapped_functions[] = {
19041897
{NULL}
19051898
};
19061899

1907-
static struct PyModuleDef overlapped_module = {
1908-
PyModuleDef_HEAD_INIT,
1909-
"_overlapped",
1910-
NULL,
1911-
-1,
1912-
overlapped_functions,
1913-
NULL,
1914-
NULL,
1915-
NULL,
1916-
NULL
1917-
};
1900+
static int
1901+
overlapped_traverse(PyObject *module, visitproc visit, void *arg)
1902+
{
1903+
OverlappedState *state = overlapped_get_state(module);
1904+
Py_VISIT(state->overlapped_type);
1905+
return 0;
1906+
}
19181907

1919-
#define WINAPI_CONSTANT(fmt, con) \
1920-
PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con))
1908+
static int
1909+
overlapped_clear(PyObject *module)
1910+
{
1911+
OverlappedState *state = overlapped_get_state(module);
1912+
Py_CLEAR(state->overlapped_type);
1913+
return 0;
1914+
}
19211915

1922-
PyMODINIT_FUNC
1923-
PyInit__overlapped(void)
1916+
static void
1917+
overlapped_free(void *module)
19241918
{
1925-
PyObject *m, *d;
1919+
overlapped_clear((PyObject *)module);
1920+
}
19261921

1922+
#define WINAPI_CONSTANT(fmt, con) \
1923+
do { \
1924+
PyObject *value = Py_BuildValue(fmt, con); \
1925+
if (value == NULL) { \
1926+
return -1; \
1927+
} \
1928+
if (PyModule_AddObject(module, #con, value) < 0 ) { \
1929+
Py_DECREF(value); \
1930+
return -1; \
1931+
} \
1932+
} while (0)
1933+
1934+
static int
1935+
overlapped_exec(PyObject *module)
1936+
{
19271937
/* Ensure WSAStartup() called before initializing function pointers */
1928-
m = PyImport_ImportModule("_socket");
1929-
if (!m)
1930-
return NULL;
1931-
Py_DECREF(m);
1938+
PyObject *socket_module = PyImport_ImportModule("_socket");
1939+
if (!socket_module) {
1940+
return -1;
1941+
}
19321942

1933-
if (initialize_function_pointers() < 0)
1934-
return NULL;
1943+
Py_DECREF(socket_module);
19351944

1936-
m = PyModule_Create(&overlapped_module);
1937-
if (PyModule_AddType(m, &OverlappedType) < 0) {
1938-
return NULL;
1945+
if (initialize_function_pointers() < 0) {
1946+
return -1;
19391947
}
19401948

1941-
d = PyModule_GetDict(m);
1949+
OverlappedState *st = overlapped_get_state(module);
1950+
st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec(
1951+
module, &overlapped_type_spec, NULL);
1952+
if (st->overlapped_type == NULL) {
1953+
return -1;
1954+
}
1955+
1956+
if (PyModule_AddType(module, st->overlapped_type) < 0) {
1957+
return -1;
1958+
}
19421959

19431960
WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING);
19441961
WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED);
@@ -1952,5 +1969,27 @@ PyInit__overlapped(void)
19521969
WINAPI_CONSTANT(F_DWORD, SO_UPDATE_CONNECT_CONTEXT);
19531970
WINAPI_CONSTANT(F_DWORD, TF_REUSE_SOCKET);
19541971

1955-
return m;
1972+
return 0;
1973+
}
1974+
1975+
static PyModuleDef_Slot overlapped_slots[] = {
1976+
{Py_mod_exec, overlapped_exec},
1977+
{0, NULL}
1978+
};
1979+
1980+
static struct PyModuleDef overlapped_module = {
1981+
PyModuleDef_HEAD_INIT,
1982+
.m_name = "_overlapped",
1983+
.m_size = sizeof(OverlappedState),
1984+
.m_methods = overlapped_functions,
1985+
.m_slots = overlapped_slots,
1986+
.m_traverse = overlapped_traverse,
1987+
.m_clear = overlapped_clear,
1988+
.m_free = overlapped_free
1989+
};
1990+
1991+
PyMODINIT_FUNC
1992+
PyInit__overlapped(void)
1993+
{
1994+
return PyModuleDef_Init(&overlapped_module);
19561995
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy