[3.10] bpo-42972: Fully support GC for _winapi.Overlapped (GH-26381) by Fidget-Spinner · Pull Request #26430 · python/cpython
/* Note: tp_clear (overlapped_clear) is not implemented because it requires cancelling the IO operation if it's pending and the cancellation is quite complex and can fail (see: overlapped_dealloc). */ static int overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) { Py_VISIT(self->read_buffer); Py_VISIT(self->write_buffer.obj); Py_VISIT(Py_TYPE(self)); return 0; }
static void overlapped_dealloc(OverlappedObject *self) { DWORD bytes; int err = GetLastError();
PyObject_GC_UnTrack(self); if (self->pending) { if (check_CancelIoEx() && Py_CancelIoEx(self->handle, &self->overlapped) &&
static PyType_Slot winapi_overlapped_type_slots[] = { {Py_tp_traverse, overlapped_traverse}, {Py_tp_dealloc, overlapped_dealloc}, {Py_tp_doc, "OVERLAPPED structure wrapper"}, {Py_tp_methods, overlapped_methods},
static OverlappedObject * new_overlapped(PyObject *module, HANDLE handle) { WinApiState *st = winapi_get_state(module); OverlappedObject *self = PyObject_New(OverlappedObject, st->overlapped_type); OverlappedObject *self = PyObject_GC_New(OverlappedObject, st->overlapped_type); if (!self) return NULL;
PyObject_GC_Track(self); return self; }
static int winapi_traverse(PyObject *module, visitproc visit, void *arg) { WinApiState *st = winapi_get_state(module); Py_VISIT(st->overlapped_type); return 0; }
static int winapi_clear(PyObject *module) { WinApiState *st = winapi_get_state(module); Py_CLEAR(st->overlapped_type); return 0; }
static void winapi_free(void *module) { winapi_clear((PyObject *)module); }
static struct PyModuleDef winapi_module = { PyModuleDef_HEAD_INIT, .m_name = "_winapi", .m_size = sizeof(WinApiState), .m_methods = winapi_functions, .m_slots = winapi_slots, .m_traverse = winapi_traverse, .m_clear = winapi_clear, .m_free = winapi_free, };
PyMODINIT_FUNC