This is the mail archive of the
guile@cygnus.com
mailing list for the Guile project.
Re: Weak observers (was Re: The taming of the before-gc-hook)
- To: Jost Boekemeier <jostobfe@calvados.zrz.TU-Berlin.DE>
- Subject: Re: Weak observers (was Re: The taming of the before-gc-hook)
- From: Mikael Djurfeldt <mdj@mdj-pc.nada.kth.se>
- Date: 28 Jul 1999 23:08:40 +0200
- Cc: Jim Blandy <jimb@red-bean.com>, Greg Harvey <Greg.Harvey@thezone.net>, guile@cygnus.com, djurfeldt@nada.kth.se
- Cc: djurfeldt@nada.kth.se
- References: <xy790807qgl.fsf_-_@mdj-pc.nada.kth.se> <p2t4sio21ea.fsf@grapefruit.zrz.tu-berlin.de>
Jost Boekemeier <jostobfe@calvados.zrz.TU-Berlin.DE> writes:
> An observer is a scheme function observing an environment. The
> function is called whenever a location of a (symbol . value) binding
> changes (either because it has been removed or re-exported).
Ah, now I remember. Sorry, I should have looked in Jim's proposal
instead of bothering you.
> All I need is a simple notification that "this object has been garbage
> collected".
Yes. What you'd really need here is a weak list as I think you
pointed out somewhere.
It is possible to manage with the weak types which already exists
(guardians, weak vectors, weak hashtables) but such a solution would
be a bit clumsy. In the module system we probably want something
neater.
I'd suggest this solution:
1. Since the time for removal of elements isn't very critical I
suggest that you use ordinary scheme lists. You could have one
list for ordinary observers and one for weak ones. The obvious
advantage is that accessors for such lists already exist.
2. Mark ordinary observers with scm_gc_mark (observers)
3. Mark weak ones with
ls = environment->weak_observers;
while (SCM_NIMP (ls))
{
SCM_SETGCMARK (ls);
ls = SCM_CDR (ls);
}
4. Execute the following code immediately after the sweep phase:
ls = environment->weak_observers;
while (SCM_NIMP (ls))
{
SCM next = SCM_CDR (ls);
if (SCM_FREEP (SCM_CAR ls))
SCM_SETCDR (ls, next);
ls = next;
}
The call to the code in step 4 can be placed after scm_gc_sweep () in
scm_igc ().