20
20
21
21
#define PY_SSIZE_T_CLEAN
22
22
#include <Python.h>
23
+ #include "structmember.h" // PyMemberDef
23
24
#include <stddef.h> // offsetof()
24
25
25
26
#ifndef MS_WINDOWS
@@ -113,10 +114,23 @@ typedef struct {
113
114
access_mode access ;
114
115
} mmap_object ;
115
116
117
+ typedef struct {
118
+ PyTypeObject * mmap_object_type ;
119
+ } mmap_state ;
120
+
121
+ static mmap_state *
122
+ get_mmap_state (PyObject * module )
123
+ {
124
+ mmap_state * state = PyModule_GetState (module );
125
+ assert (state );
126
+ return state ;
127
+ }
116
128
117
129
static void
118
130
mmap_object_dealloc (mmap_object * m_obj )
119
131
{
132
+ PyTypeObject * tp = Py_TYPE (m_obj );
133
+
120
134
#ifdef MS_WINDOWS
121
135
Py_BEGIN_ALLOW_THREADS
122
136
if (m_obj -> data != NULL)
@@ -142,7 +156,9 @@ mmap_object_dealloc(mmap_object *m_obj)
142
156
143
157
if (m_obj -> weakreflist != NULL )
144
158
PyObject_ClearWeakRefs ((PyObject * ) m_obj );
145
- Py_TYPE (m_obj )-> tp_free ((PyObject * )m_obj );
159
+
160
+ tp -> tp_free (m_obj );
161
+ Py_DECREF (tp );
146
162
}
147
163
148
164
static PyObject *
@@ -793,6 +809,11 @@ mmap_madvise_method(mmap_object *self, PyObject *args)
793
809
}
794
810
#endif // HAVE_MADVISE
795
811
812
+ static struct PyMemberDef mmap_object_members [] = {
813
+ {"__weaklistoffset__" , T_PYSSIZET , offsetof(mmap_object , weakreflist ), READONLY },
814
+ {NULL },
815
+ };
816
+
796
817
static struct PyMethodDef mmap_object_methods [] = {
797
818
{"close" , (PyCFunction ) mmap_close_method , METH_NOARGS },
798
819
{"find" , (PyCFunction ) mmap_find_method , METH_VARARGS },
@@ -1035,27 +1056,6 @@ mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value)
1035
1056
}
1036
1057
}
1037
1058
1038
- static PySequenceMethods mmap_as_sequence = {
1039
- (lenfunc )mmap_length , /*sq_length*/
1040
- 0 , /*sq_concat*/
1041
- 0 , /*sq_repeat*/
1042
- (ssizeargfunc )mmap_item , /*sq_item*/
1043
- 0 , /*sq_slice*/
1044
- (ssizeobjargproc )mmap_ass_item , /*sq_ass_item*/
1045
- 0 , /*sq_ass_slice*/
1046
- };
1047
-
1048
- static PyMappingMethods mmap_as_mapping = {
1049
- (lenfunc )mmap_length ,
1050
- (binaryfunc )mmap_subscript ,
1051
- (objobjargproc )mmap_ass_subscript ,
1052
- };
1053
-
1054
- static PyBufferProcs mmap_as_buffer = {
1055
- (getbufferproc )mmap_buffer_getbuf ,
1056
- (releasebufferproc )mmap_buffer_releasebuf ,
1057
- };
1058
-
1059
1059
static PyObject *
1060
1060
new_mmap_object (PyTypeObject * type , PyObject * args , PyObject * kwdict );
1061
1061
@@ -1083,47 +1083,39 @@ The default value is MAP_SHARED.\n\
1083
1083
To map anonymous memory, pass -1 as the fileno (both versions)." );
1084
1084
1085
1085
1086
- static PyTypeObject mmap_object_type = {
1087
- PyVarObject_HEAD_INIT (NULL , 0 )
1088
- "mmap.mmap" , /* tp_name */
1089
- sizeof (mmap_object ), /* tp_basicsize */
1090
- 0 , /* tp_itemsize */
1091
- /* methods */
1092
- (destructor )mmap_object_dealloc , /* tp_dealloc */
1093
- 0 , /* tp_vectorcall_offset */
1094
- 0 , /* tp_getattr */
1095
- 0 , /* tp_setattr */
1096
- 0 , /* tp_as_async */
1097
- (reprfunc )mmap__repr__method , /* tp_repr */
1098
- 0 , /* tp_as_number */
1099
- & mmap_as_sequence , /* tp_as_sequence */
1100
- & mmap_as_mapping , /* tp_as_mapping */
1101
- 0 , /* tp_hash */
1102
- 0 , /* tp_call */
1103
- 0 , /* tp_str */
1104
- PyObject_GenericGetAttr , /* tp_getattro */
1105
- 0 , /* tp_setattro */
1106
- & mmap_as_buffer , /* tp_as_buffer */
1107
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE , /* tp_flags */
1108
- mmap_doc , /* tp_doc */
1109
- 0 , /* tp_traverse */
1110
- 0 , /* tp_clear */
1111
- 0 , /* tp_richcompare */
1112
- offsetof(mmap_object , weakreflist ), /* tp_weaklistoffset */
1113
- 0 , /* tp_iter */
1114
- 0 , /* tp_iternext */
1115
- mmap_object_methods , /* tp_methods */
1116
- 0 , /* tp_members */
1117
- mmap_object_getset , /* tp_getset */
1118
- 0 , /* tp_base */
1119
- 0 , /* tp_dict */
1120
- 0 , /* tp_descr_get */
1121
- 0 , /* tp_descr_set */
1122
- 0 , /* tp_dictoffset */
1123
- 0 , /* tp_init */
1124
- PyType_GenericAlloc , /* tp_alloc */
1125
- new_mmap_object , /* tp_new */
1126
- PyObject_Del , /* tp_free */
1086
+ static PyType_Slot mmap_object_slots [] = {
1087
+ {Py_tp_new , new_mmap_object },
1088
+ {Py_tp_alloc , PyType_GenericAlloc },
1089
+ {Py_tp_dealloc , mmap_object_dealloc },
1090
+ {Py_tp_free , PyObject_Del },
1091
+ {Py_tp_repr , mmap__repr__method },
1092
+ {Py_tp_doc , (void * )mmap_doc },
1093
+ {Py_tp_methods , mmap_object_methods },
1094
+ {Py_tp_members , mmap_object_members },
1095
+ {Py_tp_getset , mmap_object_getset },
1096
+ {Py_tp_getattro , PyObject_GenericGetAttr },
1097
+
1098
+ /* as sequence */
1099
+ {Py_sq_length , mmap_length },
1100
+ {Py_sq_item , mmap_item },
1101
+ {Py_sq_ass_item , mmap_ass_item },
1102
+
1103
+ /* as mapping */
1104
+ {Py_mp_length , mmap_length },
1105
+ {Py_mp_subscript , mmap_subscript },
1106
+ {Py_mp_ass_subscript , mmap_ass_subscript },
1107
+
1108
+ /* as buffer */
1109
+ {Py_bf_getbuffer , mmap_buffer_getbuf },
1110
+ {Py_bf_releasebuffer , mmap_buffer_releasebuf },
1111
+ {0 , NULL },
1112
+ };
1113
+
1114
+ static PyType_Spec mmap_object_spec = {
1115
+ .name = "mmap.mmap" ,
1116
+ .basicsize = sizeof (mmap_object ),
1117
+ .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
1118
+ .slots = mmap_object_slots ,
1127
1119
};
1128
1120
1129
1121
@@ -1509,19 +1501,46 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
1509
1501
}
1510
1502
#endif /* MS_WINDOWS */
1511
1503
1504
+ static int
1505
+ mmap_traverse (PyObject * module , visitproc visit , void * arg )
1506
+ {
1507
+ mmap_state * state = get_mmap_state (module );
1508
+ Py_VISIT (state -> mmap_object_type );
1509
+ return 0 ;
1510
+ }
1511
+
1512
+ static int
1513
+ mmap_clear (PyObject * module )
1514
+ {
1515
+ mmap_state * state = get_mmap_state (module );
1516
+ Py_CLEAR (state -> mmap_object_type );
1517
+ return 0 ;
1518
+ }
1519
+
1520
+ static void
1521
+ mmap_free (void * module )
1522
+ {
1523
+ mmap_clear ((PyObject * )module );
1524
+ }
1525
+
1512
1526
static int
1513
1527
mmap_exec (PyObject * module )
1514
1528
{
1515
- if (PyType_Ready (& mmap_object_type ) < 0 ) {
1516
- return -1 ;
1517
- }
1529
+ mmap_state * state = get_mmap_state (module );
1518
1530
1519
1531
Py_INCREF (PyExc_OSError );
1520
1532
if (PyModule_AddObject (module , "error" , PyExc_OSError ) < 0 ) {
1521
1533
Py_DECREF (PyExc_OSError );
1522
1534
return -1 ;
1523
1535
}
1524
- if (PyModule_AddType (module , & mmap_object_type ) < 0 ) {
1536
+
1537
+ state -> mmap_object_type = (PyTypeObject * )PyType_FromModuleAndSpec (module ,
1538
+ & mmap_object_spec ,
1539
+ NULL );
1540
+ if (state -> mmap_object_type == NULL ) {
1541
+ return -1 ;
1542
+ }
1543
+ if (PyModule_AddType (module , state -> mmap_object_type ) < 0 ) {
1525
1544
return -1 ;
1526
1545
}
1527
1546
@@ -1660,8 +1679,11 @@ static PyModuleDef_Slot mmap_slots[] = {
1660
1679
static struct PyModuleDef mmapmodule = {
1661
1680
PyModuleDef_HEAD_INIT ,
1662
1681
.m_name = "mmap" ,
1663
- .m_size = 0 ,
1682
+ .m_size = sizeof ( mmap_state ) ,
1664
1683
.m_slots = mmap_slots ,
1684
+ .m_traverse = mmap_traverse ,
1685
+ .m_clear = mmap_clear ,
1686
+ .m_free = mmap_free ,
1665
1687
};
1666
1688
1667
1689
PyMODINIT_FUNC
0 commit comments