Skip to content

Commit ca45cf2

Browse files
committed
FEAT: allow extension to mark handle's context on free call and so prevent it from releasing
1 parent 2c45651 commit ca45cf2

File tree

2 files changed

+13
-5
lines changed

2 files changed

+13
-5
lines changed

src/core/m-gc.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -621,8 +621,7 @@ static void Mark_Series(REBSER *series, REBCNT depth);
621621
if (IS_MARK_HOB(hob))
622622
UNMARK_HOB(hob);
623623
else {
624-
Free_Hob(hob);
625-
count++;
624+
count += Free_Hob(hob);
626625
}
627626
}
628627
hob++;

src/core/m-pools.c

+12-3
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ const REBPOOLSPEC Mem_Pool_Spec[MAX_POOLS] =
604604

605605
/***********************************************************************
606606
**
607-
*/ void Free_Hob(REBHOB *hob)
607+
*/ int Free_Hob(REBHOB *hob)
608608
/*
609609
** Free a hob, returning its memory for reuse.
610610
**
@@ -613,19 +613,28 @@ const REBPOOLSPEC Mem_Pool_Spec[MAX_POOLS] =
613613
REBHSP spec;
614614
REBCNT idx = hob->index;
615615

616-
if( !IS_USED_HOB(hob) || hob->data == NULL ) return;
616+
if( !IS_USED_HOB(hob) || hob->data == NULL ) return 0;
617617

618618
spec = PG_Handles[idx];
619619
//printf("HOB %p free mem: %p %i\n", hob, hob->data, spec.flags);
620620

621621
if (spec.free) {
622-
spec.free(spec.flags & HANDLE_REQUIRES_HOB_ON_FREE ? (void*)hob : (void*)hob->data);
622+
if (spec.flags & HANDLE_REQUIRES_HOB_ON_FREE) {
623+
spec.free((void*)hob);
624+
// Although there are no references, the extension may still need the handle.
625+
// If extension marks the hob, do not free it now.
626+
if (IS_MARK_HOB(hob)) return 0;
627+
}
628+
else {
629+
spec.free(hob->data);
630+
}
623631
}
624632

625633
CLEAR(hob->data, spec.size);
626634
FREE_MEM(hob->data);
627635
UNUSE_HOB(hob);
628636
Free_Node(HOB_POOL, (REBNOD *)hob);
637+
return 1;
629638
}
630639

631640

0 commit comments

Comments
 (0)