diff options
author | Takano Akio <aljee@hyper.cx> | 2013-04-18 18:30:23 +0900 |
---|---|---|
committer | Ian Lynagh <ian@well-typed.com> | 2013-06-15 16:23:09 +0100 |
commit | d61c623ed6b2d352474a7497a65015dbf6a72e12 (patch) | |
tree | 13132eb4473fb8594bd72e168f918ea79a0c9da6 /rts/sm | |
parent | 5d9e686c30a00be08a04d9fd1c860994153a1f7a (diff) | |
download | haskell-d61c623ed6b2d352474a7497a65015dbf6a72e12.tar.gz |
Allow multiple C finalizers to be attached to a Weak#
The commit replaces mkWeakForeignEnv# with addCFinalizerToWeak#.
This new primop mutates an existing Weak# object and adds a new
C finalizer to it.
This change removes an invariant in MarkWeak.c, namely that the relative
order of Weak# objects in the list needs to be preserved across GC. This
makes it easier to split the list into per-generation structures.
The patch also removes a race condition between two threads calling
finalizeWeak# on the same WEAK object at that same time.
Diffstat (limited to 'rts/sm')
-rw-r--r-- | rts/sm/Compact.c | 2 | ||||
-rw-r--r-- | rts/sm/MarkWeak.c | 5 |
2 files changed, 3 insertions, 4 deletions
diff --git a/rts/sm/Compact.c b/rts/sm/Compact.c index 7c89418ab9..ffa355ae9c 100644 --- a/rts/sm/Compact.c +++ b/rts/sm/Compact.c @@ -620,7 +620,7 @@ thread_obj (StgInfoTable *info, StgPtr p) case WEAK: { StgWeak *w = (StgWeak *)p; - thread(&w->cfinalizer); + thread(&w->cfinalizers); thread(&w->key); thread(&w->value); thread(&w->finalizer); diff --git a/rts/sm/MarkWeak.c b/rts/sm/MarkWeak.c index d57f7a094b..f8ccaad7ea 100644 --- a/rts/sm/MarkWeak.c +++ b/rts/sm/MarkWeak.c @@ -122,7 +122,7 @@ traverseWeakPtrList(void) * called on a live weak pointer object. Just remove it. */ if (w->header.info == &stg_DEAD_WEAK_info) { - next_w = ((StgDeadWeak *)w)->link; + next_w = w->link; *last_w = next_w; continue; } @@ -144,7 +144,6 @@ traverseWeakPtrList(void) next_w = w->link; // and put it on the new weak ptr list. - // NB. we must retain the order of the weak_ptr_list (#7160) if (weak_ptr_list == NULL) { weak_ptr_list = w; } else { @@ -332,7 +331,7 @@ markWeakPtrList ( void ) evacuate((StgClosure **)last_w); w = *last_w; if (w->header.info == &stg_DEAD_WEAK_info) { - last_w = &(((StgDeadWeak*)w)->link); + last_w = &(w->link); } else { last_w = &(w->link); } |