35
35
/* See http://www.python.org/2.4/license for licensing details. */
36
36
37
37
#include "Python.h"
38
+ #include "moduleobject.h" // PyModuleDef_Slot
38
39
#include "structmember.h" // PyMemberDef
39
40
41
+
40
42
#define WINDOWS_LEAN_AND_MEAN
41
43
#include "windows.h"
42
44
#include <crtdbg.h>
@@ -78,6 +80,17 @@ check_CancelIoEx()
78
80
return has_CancelIoEx ;
79
81
}
80
82
83
+ typedef struct {
84
+ PyTypeObject * overlapped_type ;
85
+ } WinApiState ;
86
+
87
+ static inline WinApiState *
88
+ winapi_get_state (PyObject * module )
89
+ {
90
+ void * state = PyModule_GetState (module );
91
+ assert (state != NULL );
92
+ return (WinApiState * )state ;
93
+ }
81
94
82
95
/*
83
96
* A Python object wrapping an OVERLAPPED structure and other useful data
@@ -140,7 +153,9 @@ overlapped_dealloc(OverlappedObject *self)
140
153
if (self -> write_buffer .obj )
141
154
PyBuffer_Release (& self -> write_buffer );
142
155
Py_CLEAR (self -> read_buffer );
143
- PyObject_Del (self );
156
+ PyTypeObject * tp = Py_TYPE (self );
157
+ tp -> tp_free (self );
158
+ Py_DECREF (tp );
144
159
}
145
160
146
161
/*[clinic input]
@@ -305,55 +320,29 @@ static PyMemberDef overlapped_members[] = {
305
320
{NULL }
306
321
};
307
322
308
- PyTypeObject OverlappedType = {
309
- PyVarObject_HEAD_INIT (NULL , 0 )
310
- /* tp_name */ "_winapi.Overlapped" ,
311
- /* tp_basicsize */ sizeof (OverlappedObject ),
312
- /* tp_itemsize */ 0 ,
313
- /* tp_dealloc */ (destructor ) overlapped_dealloc ,
314
- /* tp_vectorcall_offset */ 0 ,
315
- /* tp_getattr */ 0 ,
316
- /* tp_setattr */ 0 ,
317
- /* tp_as_async */ 0 ,
318
- /* tp_repr */ 0 ,
319
- /* tp_as_number */ 0 ,
320
- /* tp_as_sequence */ 0 ,
321
- /* tp_as_mapping */ 0 ,
322
- /* tp_hash */ 0 ,
323
- /* tp_call */ 0 ,
324
- /* tp_str */ 0 ,
325
- /* tp_getattro */ 0 ,
326
- /* tp_setattro */ 0 ,
327
- /* tp_as_buffer */ 0 ,
328
- /* tp_flags */ Py_TPFLAGS_DEFAULT ,
329
- /* tp_doc */ "OVERLAPPED structure wrapper" ,
330
- /* tp_traverse */ 0 ,
331
- /* tp_clear */ 0 ,
332
- /* tp_richcompare */ 0 ,
333
- /* tp_weaklistoffset */ 0 ,
334
- /* tp_iter */ 0 ,
335
- /* tp_iternext */ 0 ,
336
- /* tp_methods */ overlapped_methods ,
337
- /* tp_members */ overlapped_members ,
338
- /* tp_getset */ 0 ,
339
- /* tp_base */ 0 ,
340
- /* tp_dict */ 0 ,
341
- /* tp_descr_get */ 0 ,
342
- /* tp_descr_set */ 0 ,
343
- /* tp_dictoffset */ 0 ,
344
- /* tp_init */ 0 ,
345
- /* tp_alloc */ 0 ,
346
- /* tp_new */ 0 ,
323
+ static PyType_Slot winapi_overlapped_type_slots [] = {
324
+ {Py_tp_dealloc , overlapped_dealloc },
325
+ {Py_tp_doc , "OVERLAPPED structure wrapper" },
326
+ {Py_tp_methods , overlapped_methods },
327
+ {Py_tp_members , overlapped_members },
328
+ {0 ,0 }
329
+ };
330
+
331
+ static PyType_Spec winapi_overlapped_type_spec = {
332
+ .name = "_winapi.Overlapped" ,
333
+ .basicsize = sizeof (OverlappedObject ),
334
+ .flags = Py_TPFLAGS_DEFAULT ,
335
+ .slots = winapi_overlapped_type_slots ,
347
336
};
348
337
349
338
static OverlappedObject *
350
- new_overlapped (HANDLE handle )
339
+ new_overlapped (PyObject * module , HANDLE handle )
351
340
{
352
- OverlappedObject * self ;
353
-
354
- self = PyObject_New (OverlappedObject , & OverlappedType );
341
+ WinApiState * st = winapi_get_state (module );
342
+ OverlappedObject * self = PyObject_New (OverlappedObject , st -> overlapped_type );
355
343
if (!self )
356
344
return NULL ;
345
+
357
346
self -> handle = handle ;
358
347
self -> read_buffer = NULL ;
359
348
self -> pending = 0 ;
@@ -409,7 +398,7 @@ _winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle,
409
398
OverlappedObject * overlapped = NULL ;
410
399
411
400
if (use_overlapped ) {
412
- overlapped = new_overlapped (handle );
401
+ overlapped = new_overlapped (module , handle );
413
402
if (!overlapped )
414
403
return NULL ;
415
404
}
@@ -1527,7 +1516,7 @@ _winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size,
1527
1516
if (!buf )
1528
1517
return NULL ;
1529
1518
if (use_overlapped ) {
1530
- overlapped = new_overlapped (handle );
1519
+ overlapped = new_overlapped (module , handle );
1531
1520
if (!overlapped ) {
1532
1521
Py_DECREF (buf );
1533
1522
return NULL ;
@@ -1810,7 +1799,7 @@ _winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer,
1810
1799
OverlappedObject * overlapped = NULL ;
1811
1800
1812
1801
if (use_overlapped ) {
1813
- overlapped = new_overlapped (handle );
1802
+ overlapped = new_overlapped (module , handle );
1814
1803
if (!overlapped )
1815
1804
return NULL ;
1816
1805
buf = & overlapped -> write_buffer ;
@@ -1921,36 +1910,33 @@ static PyMethodDef winapi_functions[] = {
1921
1910
{NULL , NULL }
1922
1911
};
1923
1912
1924
- static struct PyModuleDef winapi_module = {
1925
- PyModuleDef_HEAD_INIT ,
1926
- "_winapi" ,
1927
- NULL ,
1928
- -1 ,
1929
- winapi_functions ,
1930
- NULL ,
1931
- NULL ,
1932
- NULL ,
1933
- NULL
1934
- };
1935
-
1936
1913
#define WINAPI_CONSTANT (fmt , con ) \
1937
- PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con))
1938
-
1939
- PyMODINIT_FUNC
1940
- PyInit__winapi (void )
1914
+ do { \
1915
+ PyObject *value = Py_BuildValue(fmt, con); \
1916
+ if (value == NULL) { \
1917
+ return -1; \
1918
+ } \
1919
+ if (PyDict_SetItemString(d, #con, value) < 0) { \
1920
+ Py_DECREF(value); \
1921
+ return -1; \
1922
+ } \
1923
+ Py_DECREF(value); \
1924
+ } while (0)
1925
+
1926
+ static int winapi_exec (PyObject * m )
1941
1927
{
1942
- PyObject * d ;
1943
- PyObject * m ;
1928
+ WinApiState * st = winapi_get_state (m );
1944
1929
1945
- if (PyType_Ready (& OverlappedType ) < 0 )
1946
- return NULL ;
1930
+ st -> overlapped_type = (PyTypeObject * )PyType_FromModuleAndSpec (m , & winapi_overlapped_type_spec , NULL );
1931
+ if (st -> overlapped_type == NULL ) {
1932
+ return -1 ;
1933
+ }
1947
1934
1948
- m = PyModule_Create (& winapi_module );
1949
- if (m == NULL )
1950
- return NULL ;
1951
- d = PyModule_GetDict (m );
1935
+ if (PyModule_AddType (m , st -> overlapped_type ) < 0 ) {
1936
+ return -1 ;
1937
+ }
1952
1938
1953
- PyDict_SetItemString ( d , "Overlapped" , ( PyObject * ) & OverlappedType );
1939
+ PyObject * d = PyModule_GetDict ( m );
1954
1940
1955
1941
/* constants */
1956
1942
WINAPI_CONSTANT (F_DWORD , CREATE_NEW_CONSOLE );
@@ -2049,5 +2035,24 @@ PyInit__winapi(void)
2049
2035
2050
2036
WINAPI_CONSTANT ("i" , NULL );
2051
2037
2052
- return m ;
2038
+ return 0 ;
2039
+ }
2040
+
2041
+ static PyModuleDef_Slot winapi_slots [] = {
2042
+ {Py_mod_exec , winapi_exec },
2043
+ {0 , NULL }
2044
+ };
2045
+
2046
+ static struct PyModuleDef winapi_module = {
2047
+ PyModuleDef_HEAD_INIT ,
2048
+ .m_name = "_winapi" ,
2049
+ .m_size = sizeof (WinApiState ),
2050
+ .m_methods = winapi_functions ,
2051
+ .m_slots = winapi_slots ,
2052
+ };
2053
+
2054
+ PyMODINIT_FUNC
2055
+ PyInit__winapi (void )
2056
+ {
2057
+ return PyModuleDef_Init (& winapi_module );
2053
2058
}
0 commit comments