[project @ 1999-02-02 14:17:05 by simonm]
[ghc-hetmet.git] / ghc / rts / Weak.c
1 /* -----------------------------------------------------------------------------
2  * $Id: Weak.c,v 1.5 1999/02/01 18:05:35 simonm Exp $
3  *
4  * Weak pointers / finalisers
5  *
6  * ---------------------------------------------------------------------------*/
7
8 #include "Rts.h"
9 #include "RtsAPI.h"
10 #include "RtsFlags.h"
11 #include "Weak.h"
12 #include "Storage.h"
13
14 StgWeak *weak_ptr_list;
15
16 /*
17  * finaliseWeakPointersNow() is called just before the system is shut
18  * down.  It runs the finaliser for each weak pointer still in the
19  * system.
20  */
21
22 void
23 finaliseWeakPointersNow(void)
24 {
25   StgWeak *w;
26
27   for (w = weak_ptr_list; w; w = w->link) {
28     IF_DEBUG(weak,fprintf(stderr,"Finalising weak pointer at %p -> %p\n", w, w->key));
29     w->header.info = &DEAD_WEAK_info;
30     if (w->finaliser != &NO_FINALISER_info) {
31       rts_evalIO(w->finaliser,NULL);
32     }
33   }
34
35
36 /*
37  * scheduleFinalisers() is called on the list of weak pointers found
38  * to be dead after a garbage collection.  It overwrites each object
39  * with DEAD_WEAK, and creates a new thread for the finaliser.
40  */
41
42 void
43 scheduleFinalisers(StgWeak *list)
44 {
45   StgWeak *w;
46   
47   for (w = list; w; w = w->link) {
48     IF_DEBUG(weak,fprintf(stderr,"Finalising weak pointer at %p -> %p\n", w, w->key));
49     if (w->finaliser != &NO_FINALISER_info) {
50 #ifdef INTERPRETER
51       createGenThread(RtsFlags.GcFlags.initialStkSize, w->finaliser);
52 #else
53       createIOThread(RtsFlags.GcFlags.initialStkSize, w->finaliser);
54 #endif
55     }
56     w->header.info = &DEAD_WEAK_info;
57   }
58 }
59
60 void
61 markWeakList(void)
62 {
63   StgWeak *w, **last_w;
64
65   last_w = &weak_ptr_list;
66   for (w = weak_ptr_list; w; w = w->link) {
67     w = (StgWeak *)MarkRoot((StgClosure *)w);
68     *last_w = w;
69     last_w = &(w->link);
70   }
71 }
72