summaryrefslogtreecommitdiff
path: root/libnetfs/nrele.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnetfs/nrele.c')
-rw-r--r--libnetfs/nrele.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/libnetfs/nrele.c b/libnetfs/nrele.c
index 6f9a0144..4dddd1f4 100644
--- a/libnetfs/nrele.c
+++ b/libnetfs/nrele.c
@@ -23,15 +23,38 @@
void
netfs_nrele (struct node *np)
{
- pthread_spin_lock (&netfs_node_refcnt_lock);
- assert (np->references);
- np->references--;
- if (np->references == 0)
+ struct references result;
+ int locked = FALSE;
+
+ refcounts_demote (&np->refcounts, &result);
+
+ if (result.hard == 0)
+ {
+ pthread_mutex_lock (&np->lock);
+ netfs_try_dropping_softrefs (np);
+ locked = TRUE;
+ }
+
+ refcounts_deref_weak (&np->refcounts, &result);
+
+ if (result.hard == 0 && result.weak == 0)
+ {
+ if (! locked)
+ pthread_mutex_lock (&np->lock);
+ netfs_drop_node (np);
+ } else if (locked)
+ pthread_mutex_unlock (&np->lock);
+}
+
+void
+netfs_nrele_light (struct node *np)
+{
+ struct references result;
+
+ refcounts_deref_weak (&np->refcounts, &result);
+ if (result.hard == 0 && result.weak == 0)
{
pthread_mutex_lock (&np->lock);
netfs_drop_node (np);
- /* netfs_drop_node drops netfs_node_refcnt_lock for us. */
}
- else
- pthread_spin_unlock (&netfs_node_refcnt_lock);
}