@@ -44,14 +44,27 @@ pysqlite_new_node(PyObject *key, PyObject *data)
44
44
return node ;
45
45
}
46
46
47
+ static int
48
+ node_traverse (pysqlite_Node * self , visitproc visit , void * arg )
49
+ {
50
+ Py_VISIT (Py_TYPE (self ));
51
+ return 0 ;
52
+ }
53
+
54
+ static int
55
+ node_clear (pysqlite_Node * self )
56
+ {
57
+ Py_CLEAR (self -> key );
58
+ Py_CLEAR (self -> data );
59
+ return 0 ;
60
+ }
61
+
47
62
static void
48
63
pysqlite_node_dealloc (pysqlite_Node * self )
49
64
{
50
65
PyTypeObject * tp = Py_TYPE (self );
51
-
52
- Py_DECREF (self -> key );
53
- Py_DECREF (self -> data );
54
-
66
+ PyObject_GC_UnTrack (self );
67
+ tp -> tp_clear ((PyObject * )self );
55
68
tp -> tp_free (self );
56
69
Py_DECREF (tp );
57
70
}
@@ -88,31 +101,50 @@ pysqlite_cache_init(pysqlite_Cache *self, PyObject *args, PyObject *kwargs)
88
101
return 0 ;
89
102
}
90
103
91
- static void
92
- pysqlite_cache_dealloc (pysqlite_Cache * self )
104
+ static int
105
+ cache_traverse (pysqlite_Cache * self , visitproc visit , void * arg )
93
106
{
94
- PyTypeObject * tp = Py_TYPE (self );
95
- pysqlite_Node * node ;
96
- pysqlite_Node * delete_node ;
97
-
98
- if (!self -> factory ) {
99
- /* constructor failed, just get out of here */
100
- return ;
107
+ pysqlite_Node * node = self -> first ;
108
+ while (node ) {
109
+ Py_VISIT (node );
110
+ node = node -> next ;
101
111
}
112
+ Py_VISIT (self -> mapping );
113
+ if (self -> decref_factory ) {
114
+ Py_VISIT (self -> factory );
115
+ }
116
+ Py_VISIT (Py_TYPE (self ));
117
+ return 0 ;
118
+ }
102
119
120
+ static int
121
+ cache_clear (pysqlite_Cache * self )
122
+ {
103
123
/* iterate over all nodes and deallocate them */
104
- node = self -> first ;
124
+ pysqlite_Node * node = self -> first ;
105
125
while (node ) {
106
- delete_node = node ;
126
+ pysqlite_Node * delete_node = node ;
107
127
node = node -> next ;
108
- Py_DECREF (delete_node );
128
+ Py_CLEAR (delete_node );
109
129
}
110
-
111
130
if (self -> decref_factory ) {
112
- Py_DECREF (self -> factory );
131
+ Py_CLEAR (self -> factory );
132
+ }
133
+ Py_CLEAR (self -> mapping );
134
+ return 0 ;
135
+ }
136
+
137
+ static void
138
+ pysqlite_cache_dealloc (pysqlite_Cache * self )
139
+ {
140
+ if (!self -> factory ) {
141
+ /* constructor failed, just get out of here */
142
+ return ;
113
143
}
114
- Py_DECREF (self -> mapping );
115
144
145
+ PyObject_GC_UnTrack (self );
146
+ PyTypeObject * tp = Py_TYPE (self );
147
+ tp -> tp_clear ((PyObject * )self );
116
148
tp -> tp_free (self );
117
149
Py_DECREF (tp );
118
150
}
@@ -260,14 +292,15 @@ pysqlite_cache_display(pysqlite_Cache *self, PyObject *args)
260
292
261
293
static PyType_Slot node_slots [] = {
262
294
{Py_tp_dealloc , pysqlite_node_dealloc },
263
- {Py_tp_new , PyType_GenericNew },
295
+ {Py_tp_traverse , node_traverse },
296
+ {Py_tp_clear , node_clear },
264
297
{0 , NULL },
265
298
};
266
299
267
300
static PyType_Spec node_spec = {
268
301
.name = MODULE_NAME ".Node" ,
269
302
.basicsize = sizeof (pysqlite_Node ),
270
- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
303
+ .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC ,
271
304
.slots = node_slots ,
272
305
};
273
306
PyTypeObject * pysqlite_NodeType = NULL ;
@@ -283,15 +316,16 @@ static PyMethodDef cache_methods[] = {
283
316
static PyType_Slot cache_slots [] = {
284
317
{Py_tp_dealloc , pysqlite_cache_dealloc },
285
318
{Py_tp_methods , cache_methods },
286
- {Py_tp_new , PyType_GenericNew },
287
319
{Py_tp_init , pysqlite_cache_init },
320
+ {Py_tp_traverse , cache_traverse },
321
+ {Py_tp_clear , cache_clear },
288
322
{0 , NULL },
289
323
};
290
324
291
325
static PyType_Spec cache_spec = {
292
326
.name = MODULE_NAME ".Cache" ,
293
327
.basicsize = sizeof (pysqlite_Cache ),
294
- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
328
+ .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC ,
295
329
.slots = cache_slots ,
296
330
};
297
331
PyTypeObject * pysqlite_CacheType = NULL ;
0 commit comments