summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2018-01-06 01:13:02 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2018-01-06 01:13:02 +0100
commita7c7e4c642aa284cb57a855ea94bab90cc2dae3e (patch)
tree8e16d76d65f75da93cb754ef5e9a8f4b6ed77cd9
parent051c0a77360a629e047d5267b05cde4cdba0e064 (diff)
libfshelp/get-identity.c: Avoid spurious ihash removal
Reported by Brent W. Baccala. While some thread has converted a hardref to a weakref and tries to release the hash weakref, another thread might reacquire a hardref, and then convert it to a weakref and try to release it. We thus have to make sure that we really have the last weakref before removing from the hash. * libfshelp/get-identity.c (id_clean): Also check that there are only two weak refs left.
-rw-r--r--libfshelp/get-identity.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/libfshelp/get-identity.c b/libfshelp/get-identity.c
index f88e0f82..96de55a8 100644
--- a/libfshelp/get-identity.c
+++ b/libfshelp/get-identity.c
@@ -69,10 +69,13 @@ static void
id_clean (void *cookie)
{
struct idspec *i = cookie;
+ struct references result;
pthread_mutex_lock (&idlock);
- if (refcounts_hard_references(&i->pi.refcounts) == 0)
+ refcounts_references (&i->pi.refcounts, &result);
+ if (result.hard == 0 && result.weak == 2)
{
- /* Nobody got a send right in between, we can remove from the hash. */
+ /* Nobody got a send right in between and we have the last weak reference
+ in addition to our caller's, so we can remove from the hash. */
hurd_ihash_locp_remove (&idhash, i->id_hashloc);
ports_port_deref_weak (&i->pi);
}