diff options
Diffstat (limited to 'libnetfs/nrele.c')
-rw-r--r-- | libnetfs/nrele.c | 37 |
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); } |