summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorMohamed Koubaa <koubaa.m@gmail.com>2020-09-07 13:12:40 (GMT)
committerGitHub <noreply@github.com>2020-09-07 13:12:40 (GMT)
commit2aabc3200bf03d2ec1aa987e1e20db704948111e (patch)
tree2d6fecfddb24e2590fc3baaa4dfb704f9cb14c0a /Modules
parent426f2b4f13f392875e7861dbd7f34735731eff17 (diff)
downloadcpython-2aabc3200bf03d2ec1aa987e1e20db704948111e.zip
cpython-2aabc3200bf03d2ec1aa987e1e20db704948111e.tar.gz
cpython-2aabc3200bf03d2ec1aa987e1e20db704948111e.tar.bz2
bpo-1635741: Port _overlapped module to multi-phase init (GH-22051)
Port the _overlapped extension module to multi-phase initialization (PEP 489).
Diffstat (limited to 'Modules')
-rw-r--r--Modules/overlapped.c173
1 files changed, 106 insertions, 67 deletions
diff --git a/Modules/overlapped.c b/Modules/overlapped.c
index 5e7a1bb..3829932 100644
--- a/Modules/overlapped.c
+++ b/Modules/overlapped.c
@@ -100,6 +100,19 @@ typedef struct {
};
} OverlappedObject;
+typedef struct {
+ PyTypeObject *overlapped_type;
+} OverlappedState;
+
+static inline OverlappedState*
+overlapped_get_state(PyObject *module)
+{
+ void *state = PyModule_GetState(module);
+ assert(state != NULL);
+ return (OverlappedState *)state;
+}
+
+
/*
* Map Windows error codes to subclasses of OSError
*/
@@ -706,8 +719,11 @@ Overlapped_dealloc(OverlappedObject *self)
}
Overlapped_clear(self);
- PyObject_Del(self);
SetLastError(olderr);
+
+ PyTypeObject *tp = Py_TYPE(self);
+ PyObject_Del(self);
+ Py_DECREF(tp);
}
@@ -1846,45 +1862,22 @@ static PyGetSetDef Overlapped_getsets[] = {
{NULL},
};
-PyTypeObject OverlappedType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- /* tp_name */ "_overlapped.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_Overlapped__doc__,
- /* tp_traverse */ (traverseproc)Overlapped_traverse,
- /* 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 */ Overlapped_getsets,
- /* 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 */ _overlapped_Overlapped,
+static PyType_Slot overlapped_type_slots[] = {
+ {Py_tp_dealloc, Overlapped_dealloc},
+ {Py_tp_doc, (char *)_overlapped_Overlapped__doc__},
+ {Py_tp_traverse, Overlapped_traverse},
+ {Py_tp_methods, Overlapped_methods},
+ {Py_tp_members, Overlapped_members},
+ {Py_tp_getset, Overlapped_getsets},
+ {Py_tp_new, _overlapped_Overlapped},
+ {0,0}
+};
+
+static PyType_Spec overlapped_type_spec = {
+ .name = "_overlapped.Overlapped",
+ .basicsize = sizeof(OverlappedObject),
+ .flags = Py_TPFLAGS_DEFAULT,
+ .slots = overlapped_type_slots
};
static PyMethodDef overlapped_functions[] = {
@@ -1904,41 +1897,65 @@ static PyMethodDef overlapped_functions[] = {
{NULL}
};
-static struct PyModuleDef overlapped_module = {
- PyModuleDef_HEAD_INIT,
- "_overlapped",
- NULL,
- -1,
- overlapped_functions,
- NULL,
- NULL,
- NULL,
- NULL
-};
+static int
+overlapped_traverse(PyObject *module, visitproc visit, void *arg)
+{
+ OverlappedState *state = overlapped_get_state(module);
+ Py_VISIT(state->overlapped_type);
+ return 0;
+}
-#define WINAPI_CONSTANT(fmt, con) \
- PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con))
+static int
+overlapped_clear(PyObject *module)
+{
+ OverlappedState *state = overlapped_get_state(module);
+ Py_CLEAR(state->overlapped_type);
+ return 0;
+}
-PyMODINIT_FUNC
-PyInit__overlapped(void)
+static void
+overlapped_free(void *module)
{
- PyObject *m, *d;
+ overlapped_clear((PyObject *)module);
+}
+#define WINAPI_CONSTANT(fmt, con) \
+ do { \
+ PyObject *value = Py_BuildValue(fmt, con); \
+ if (value == NULL) { \
+ return -1; \
+ } \
+ if (PyModule_AddObject(module, #con, value) < 0 ) { \
+ Py_DECREF(value); \
+ return -1; \
+ } \
+ } while (0)
+
+static int
+overlapped_exec(PyObject *module)
+{
/* Ensure WSAStartup() called before initializing function pointers */
- m = PyImport_ImportModule("_socket");
- if (!m)
- return NULL;
- Py_DECREF(m);
+ PyObject *socket_module = PyImport_ImportModule("_socket");
+ if (!socket_module) {
+ return -1;
+ }
- if (initialize_function_pointers() < 0)
- return NULL;
+ Py_DECREF(socket_module);
- m = PyModule_Create(&overlapped_module);
- if (PyModule_AddType(m, &OverlappedType) < 0) {
- return NULL;
+ if (initialize_function_pointers() < 0) {
+ return -1;
}
- d = PyModule_GetDict(m);
+ OverlappedState *st = overlapped_get_state(module);
+ st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec(
+ module, &overlapped_type_spec, NULL);
+ if (st->overlapped_type == NULL) {
+ return -1;
+ }
+
+ if (PyModule_AddType(module, st->overlapped_type) < 0) {
+ return -1;
+ }
WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING);
WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED);
@@ -1952,5 +1969,27 @@ PyInit__overlapped(void)
WINAPI_CONSTANT(F_DWORD, SO_UPDATE_CONNECT_CONTEXT);
WINAPI_CONSTANT(F_DWORD, TF_REUSE_SOCKET);
- return m;
+ return 0;
+}
+
+static PyModuleDef_Slot overlapped_slots[] = {
+ {Py_mod_exec, overlapped_exec},
+ {0, NULL}
+};
+
+static struct PyModuleDef overlapped_module = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "_overlapped",
+ .m_size = sizeof(OverlappedState),
+ .m_methods = overlapped_functions,
+ .m_slots = overlapped_slots,
+ .m_traverse = overlapped_traverse,
+ .m_clear = overlapped_clear,
+ .m_free = overlapped_free
+};
+
+PyMODINIT_FUNC
+PyInit__overlapped(void)
+{
+ return PyModuleDef_Init(&overlapped_module);
}