Weak.c 2.08 KB
Newer Older
1
/* -----------------------------------------------------------------------------
sof's avatar
sof committed
2
 * $Id: Weak.c,v 1.11 1999/07/06 15:05:49 sof Exp $
3 4
 *
 * (c) The GHC Team, 1998-1999
5
 *
6
 * Weak pointers / finalizers
7 8 9 10 11
 *
 * ---------------------------------------------------------------------------*/

#include "Rts.h"
#include "RtsAPI.h"
sof's avatar
sof committed
12
#include "SchedAPI.h"
13 14 15 16 17 18 19
#include "RtsFlags.h"
#include "Weak.h"
#include "Storage.h"

StgWeak *weak_ptr_list;

/*
20 21
 * finalizeWeakPointersNow() is called just before the system is shut
 * down.  It runs the finalizer for each weak pointer still in the
22
 * system.
23 24 25 26
 *
 * Careful here - rts_evalIO might cause a garbage collection, which
 * might change weak_ptr_list.  Must re-load weak_ptr_list each time
 * around the loop.
27 28 29
 */

void
30
finalizeWeakPointersNow(void)
31 32
{
  StgWeak *w;
33 34 35
  
  while ((w = weak_ptr_list)) {
    weak_ptr_list = w->link;
36
    IF_DEBUG(weak,fprintf(stderr,"Finalising weak pointer at %p -> %p\n", w, w->key));
37
    w->header.info = &DEAD_WEAK_info;
38 39
    if (w->finalizer != &NO_FINALIZER_closure) {
      rts_evalIO(w->finalizer,NULL);
40
    }
41 42 43 44
  }
} 

/*
45
 * scheduleFinalizers() is called on the list of weak pointers found
46
 * to be dead after a garbage collection.  It overwrites each object
47
 * with DEAD_WEAK, and creates a new thread for the finalizer.
48 49 50 51 52 53 54
 *
 * This function is called just after GC.  The weak pointers on the
 * argument list are those whose keys were found to be not reachable,
 * however the value and finalizer fields have by now been marked live.
 * The weak pointer object itself may not be alive - i.e. we may be
 * looking at either an object in from-space or one in to-space.  It
 * doesn't really matter either way.
55 56 57
 */

void
58
scheduleFinalizers(StgWeak *list)
59 60 61 62
{
  StgWeak *w;
  
  for (w = list; w; w = w->link) {
63
    IF_DEBUG(weak,fprintf(stderr,"Finalising weak pointer at %p -> %p\n", w, w->key));
64
    if (w->finalizer != &NO_FINALIZER_closure) {
65
#ifdef INTERPRETER
66
      createGenThread(RtsFlags.GcFlags.initialStkSize, w->finalizer);
67
#else
68
      createIOThread(RtsFlags.GcFlags.initialStkSize, w->finalizer);
69
#endif
70
    }
71 72 73
    w->header.info = &DEAD_WEAK_info;
  }
}