@@ -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
18901883static 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