10000 bpo-1635741: Port _overlapped module to multi-phase init (GH-22051) · python/cpython@2aabc32 · GitHub
[go: up one dir, main page]

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)
0