Skip to content

Commit 5d6ee9c

Browse files
committed
fully implement GC protocol for lzma objects
1 parent 31d3836 commit 5d6ee9c

File tree

1 file changed

+20
-13
lines changed

1 file changed

+20
-13
lines changed

Modules/_lzmamodule.c

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -809,11 +809,14 @@ Compressor_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
809809
return NULL;
810810
}
811811

812-
assert(type != NULL && type->tp_alloc != NULL);
813-
self = (Compressor *)type->tp_alloc(type, 0);
812+
assert(type != NULL);
813+
self = PyObject_GC_New(Compressor, type);
814814
if (self == NULL) {
815815
return NULL;
816816
}
817+
/* Initialize the remaining fields (untouched by PyObject_GC_New()). */
818+
const size_t offset = sizeof(struct { PyObject_HEAD });
819+
memset((char *)self + offset, 0, sizeof(*self) - offset);
817820

818821
self->alloc.opaque = NULL;
819822
self->alloc.alloc = PyLzma_Malloc;
@@ -827,7 +830,6 @@ Compressor_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
827830
return NULL;
828831
}
829832

830-
self->flushed = 0;
831833
switch (format) {
832834
case FORMAT_XZ:
833835
if (check == -1) {
@@ -856,6 +858,7 @@ Compressor_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
856858
goto error;
857859
}
858860

861+
PyObject_GC_Track(self);
859862
return (PyObject *)self;
860863

861864
error:
@@ -866,12 +869,13 @@ Compressor_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
866869
static void
867870
Compressor_dealloc(PyObject *op)
868871
{
872+
PyTypeObject *tp = Py_TYPE(op);
873+
PyObject_GC_UnTrack(op);
869874
Compressor *self = Compressor_CAST(op);
870875
lzma_end(&self->lzs);
871876
if (self->lock != NULL) {
872877
PyThread_free_lock(self->lock);
873878
}
874-
PyTypeObject *tp = Py_TYPE(self);
875879
tp->tp_free(self);
876880
Py_DECREF(tp);
877881
}
@@ -933,7 +937,7 @@ static PyType_Spec lzma_compressor_type_spec = {
933937
// lzma_compressor_type_spec does not have Py_TPFLAGS_BASETYPE flag
934938
// which prevents to create a subclass.
935939
// So calling PyType_GetModuleState() in this file is always safe.
936-
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE),
940+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
937941
.slots = lzma_compressor_type_slots,
938942
};
939943

@@ -1241,16 +1245,19 @@ _lzma_LZMADecompressor_impl(PyTypeObject *type, int format,
12411245
return NULL;
12421246
}
12431247

1244-
assert(type != NULL && type->tp_alloc != NULL);
1245-
self = (Decompressor *)type->tp_alloc(type, 0);
1248+
assert(type != NULL);
1249+
self = PyObject_GC_New(Decompressor, type);
12461250
if (self == NULL) {
12471251
return NULL;
12481252
}
1253+
/* Initialize the remaining fields (untouched by PyObject_GC_New()). */
1254+
const size_t offset = sizeof(struct { PyObject_HEAD });
1255+
memset((char *)self + offset, 0, sizeof(*self) - offset);
1256+
12491257
self->alloc.opaque = NULL;
12501258
self->alloc.alloc = PyLzma_Malloc;
12511259
self->alloc.free = PyLzma_Free;
12521260
self->lzs.allocator = &self->alloc;
1253-
self->lzs.next_in = NULL;
12541261

12551262
self->lock = PyThread_allocate_lock();
12561263
if (self->lock == NULL) {
@@ -1261,9 +1268,7 @@ _lzma_LZMADecompressor_impl(PyTypeObject *type, int format,
12611268

12621269
self->check = LZMA_CHECK_UNKNOWN;
12631270
self->needs_input = 1;
1264-
self->input_buffer = NULL;
1265-
self->input_buffer_size = 0;
1266-
Py_XSETREF(self->unused_data, PyBytes_FromStringAndSize(NULL, 0));
1271+
self->unused_data = PyBytes_FromStringAndSize(NULL, 0);
12671272
if (self->unused_data == NULL) {
12681273
goto error;
12691274
}
@@ -1304,6 +1309,7 @@ _lzma_LZMADecompressor_impl(PyTypeObject *type, int format,
13041309
goto error;
13051310
}
13061311

1312+
PyObject_GC_Track(self);
13071313
return (PyObject *)self;
13081314

13091315
error:
@@ -1314,6 +1320,8 @@ _lzma_LZMADecompressor_impl(PyTypeObject *type, int format,
13141320
static void
13151321
Decompressor_dealloc(PyObject *op)
13161322
{
1323+
PyTypeObject *tp = Py_TYPE(op);
1324+
PyObject_GC_UnTrack(op);
13171325
Decompressor *self = Decompressor_CAST(op);
13181326
if(self->input_buffer != NULL)
13191327
PyMem_Free(self->input_buffer);
@@ -1323,7 +1331,6 @@ Decompressor_dealloc(PyObject *op)
13231331
if (self->lock != NULL) {
13241332
PyThread_free_lock(self->lock);
13251333
}
1326-
PyTypeObject *tp = Py_TYPE(self);
13271334
tp->tp_free(self);
13281335
Py_DECREF(tp);
13291336
}
@@ -1381,7 +1388,7 @@ static PyType_Spec lzma_decompressor_type_spec = {
13811388
// lzma_decompressor_type_spec does not have Py_TPFLAGS_BASETYPE flag
13821389
// which prevents to create a subclass.
13831390
// So calling PyType_GetModuleState() in this file is always safe.
1384-
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE),
1391+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
13851392
.slots = lzma_decompressor_type_slots,
13861393
};
13871394

0 commit comments

Comments
 (0)