@@ -100,6 +100,19 @@ typedef struct {
100
100
};
101
101
} OverlappedObject ;
102
102
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
+
103
116
/*
104
117
* Map Windows error codes to subclasses of OSError
105
118
*/
@@ -706,8 +719,11 @@ Overlapped_dealloc(OverlappedObject *self)
706
719
}
707
720
708
721
Overlapped_clear (self );
709
- PyObject_Del (self );
710
722
SetLastError (olderr );
723
+
724
+ PyTypeObject * tp = Py_TYPE (self );
725
+ PyObject_Del (self );
726
+ Py_DECREF (tp );
711
727
}
712
728
713
729
@@ -1846,45 +1862,22 @@ static PyGetSetDef Overlapped_getsets[] = {
1846
1862
{NULL },
1847
1863
};
1848
1864
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
1888
1881
};
1889
1882
1890
1883
static PyMethodDef overlapped_functions [] = {
@@ -1904,41 +1897,65 @@ static PyMethodDef overlapped_functions[] = {
1904
1897
{NULL }
1905
1898
};
1906
1899
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
+ }
1918
1907
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
+ }
1921
1915
1922
- PyMODINIT_FUNC
1923
- PyInit__overlapped (void )
1916
+ static void
1917
+ overlapped_free (void * module )
1924
1918
{
1925
- PyObject * m , * d ;
1919
+ overlapped_clear ((PyObject * )module );
1920
+ }
1926
1921
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
+ {
1927
1937
/* 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
+ }
1932
1942
1933
- if (initialize_function_pointers () < 0 )
1934
- return NULL ;
1943
+ Py_DECREF (socket_module );
1935
1944
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 ;
1939
1947
}
1940
1948
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
+ }
1942
1959
1943
1960
WINAPI_CONSTANT (F_DWORD , ERROR_IO_PENDING );
1944
1961
WINAPI_CONSTANT (F_DWORD , ERROR_NETNAME_DELETED );
@@ -1952,5 +1969,27 @@ PyInit__overlapped(void)
1952
1969
WINAPI_CONSTANT (F_DWORD , SO_UPDATE_CONNECT_CONTEXT );
1953
1970
WINAPI_CONSTANT (F_DWORD , TF_REUSE_SOCKET );
1954
1971
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 );
1956
1995
}
0 commit comments