summaryrefslogtreecommitdiff
path: root/rts/sm
diff options
context:
space:
mode:
authorTakano Akio <aljee@hyper.cx>2013-04-18 18:30:23 +0900
committerIan Lynagh <ian@well-typed.com>2013-06-15 16:23:09 +0100
commitd61c623ed6b2d352474a7497a65015dbf6a72e12 (patch)
tree13132eb4473fb8594bd72e168f918ea79a0c9da6 /rts/sm
parent5d9e686c30a00be08a04d9fd1c860994153a1f7a (diff)
downloadhaskell-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.c2
-rw-r--r--rts/sm/MarkWeak.c5
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);
}