summaryrefslogtreecommitdiff
path: root/libfshelp
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2017-12-19 01:39:36 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2017-12-19 01:41:48 +0100
commitb37c7dd4dd0de064b7ae2c9ad5687ebb635677c8 (patch)
tree82efcf65d6105cd926729f4a3ca55a960fdbcc1a /libfshelp
parentd3594ddad8fdd4f28f2362ad288acd03ed60eb41 (diff)
libfshelp: Add weak reference for hash table reference
Fixes reference w/o send right crash. * libfshelp/get-identity.c (fshelp_get_identity): Get weak reference for the hash table reference. (id_initialize): Pass id_clean as dropweak_routine instead of clean_routine to ports_create_class. (id_clean): Remove from hash table only if there are no hard references left, i.e. we didn't reacquired a port right in between.
Diffstat (limited to 'libfshelp')
-rw-r--r--libfshelp/get-identity.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/libfshelp/get-identity.c b/libfshelp/get-identity.c
index 17244dee..9f92272e 100644
--- a/libfshelp/get-identity.c
+++ b/libfshelp/get-identity.c
@@ -42,7 +42,12 @@ id_clean (void *cookie)
{
struct idspec *i = cookie;
pthread_mutex_lock (&idlock);
- hurd_ihash_locp_remove (&idhash, i->id_hashloc);
+ if (refcounts_hard_references(&i->pi.refcounts) == 0)
+ {
+ /* Nobody got a send right in between, we can remove from the hash. */
+ hurd_ihash_locp_remove (&idhash, i->id_hashloc);
+ ports_port_deref_weak (&i->pi);
+ }
pthread_mutex_unlock (&idlock);
}
@@ -50,7 +55,7 @@ static void
id_initialize ()
{
assert_backtrace (!idclass);
- idclass = ports_create_class (id_clean, NULL);
+ idclass = ports_create_class (NULL, id_clean);
}
error_t
@@ -75,6 +80,9 @@ fshelp_get_identity (struct port_bucket *bucket,
if (err)
goto lose_port;
+ /* Weak reference for the hash entry. */
+ ports_port_ref_weak(&i->pi);
+
*pt = ports_get_right (i);
ports_port_deref (i);
}