Skip to content

Commit 25b615a

Browse files
committed
Fix gcguard_delete for rb_objspace_call_finalizer
rb_objspace_call_finalizer calls dfree functions in the order in which the objects are lined up on the heap. So the gcguard object may be freed before the objects guarded in it. This change avoids the TypeError occurred on TypedData_Get_Struct in such the case.
1 parent 85df349 commit 25b615a

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

ext/pycall/gc.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,16 @@ gcguard_aset(VALUE gcguard, PyObject *pyptr, VALUE rbobj)
5757
static void
5858
gcguard_delete(VALUE gcguard, PyObject *pyptr)
5959
{
60-
struct gcguard *gg;
61-
st_data_t key, val;
60+
if (rb_typeddata_is_kind_of(gcguard, &gcguard_data_type)) {
61+
/* This check is necessary to avoid error on the process finalization phase */
62+
struct gcguard *gg;
63+
st_data_t key, val;
6264

63-
TypedData_Get_Struct(gcguard, struct gcguard, &gcguard_data_type, gg);
65+
TypedData_Get_Struct(gcguard, struct gcguard, &gcguard_data_type, gg);
6466

65-
key = (st_data_t)pyptr;
66-
st_delete(gg->guarded_objects, &key, &val);
67+
key = (st_data_t)pyptr;
68+
st_delete(gg->guarded_objects, &key, &val);
69+
}
6770
}
6871

6972
static ID id_gcguard_table;

0 commit comments

Comments
 (0)