diff options
author | Flavio Cruz <flaviocruz@gmail.com> | 2016-03-15 04:50:02 -0400 |
---|---|---|
committer | Justus Winter <justus@gnupg.org> | 2016-03-21 19:45:11 +0100 |
commit | 5eef605eb523e4148ccd22578327492178cfd0c4 (patch) | |
tree | aab9f03896e9acec97d99b5617bf7792f6022f0d /console | |
parent | 0da2914ac9d9321cca2d402b2c505881e436c725 (diff) |
netfs: Remove global reference count lock.
* libnetfs/drop-node.c: Remove use of netfs_node_refcnt_lock.
* libnetfs/init-init.c: Remove netfs_node_refcnt_lock.
* libnetfs/make-node.c: Initialize refcounts in refcounts_init.
* libnetfs/netfs.h: Use refcounts_t for tracking node references. Remove
netfs_node_refcnt_lock. Add netfs_nref_light, netfs_nrele_light and
handler netfs_try_dropping_softrefs. Adjust comments.
* libnetfs/nput.c: Use refcounts_t. Call netfs_try_dropping_softrefs to
remove any soft reference that the translator might have acquired
during the lifetime of the node. Implement empty
netfs_try_dropping_softrefs.
* libnetfs/nref.c: Implement netfs_nref_light.
* libnetfs/nrele.c: Use refcounts_t and netfs_try_dropping_softrefs.
Implement netfs_nrele_light.
* ftpfs/dir.c: Use netfs_nref without locking the old
netfs_node_refcnt_lock.
* ftpfs/node.c: Likewise.
* usermux/mux.c: Use netfs_nref to increase hard references of the node.
* hostmux/mux.c: Use netfs_nref to increase hard references of the node.
* trans/fakeroot.c (new_node): Use a light reference when storing a node in the
hash table.
* trans/fakeroot.c (netfs_try_dropping_softrefs): Implement
netfs_try_dropping_softrefs to remove the node from the hash table.
* trans/fakeroot.c (netfs_node_norefs): Remove code to remove the node
from the hash table.
* trans/fakeroot.c (netfs_S_dir_lookup): Simplify lookup code since we
don't need to lock netfs_node_refcnt_lock anymore.
* procfs/netfs.c: Remove use of netfs_node_refcnt_lock.
* nfs/cache.c: Add mutex to handle exclusive access to nodehash. This
replaces the use of netfs_node_refcnt_lock.
* nfs/cache.c (lookup_handle): Use nodehash_ihash_lock when accessing
nodehash. Use netfs_nref_light to add one soft reference to the node
just added to nodehash.
* nfs/cache.c (netfs_node_norefs): Use netfs_nref. Don't use
netfs_node_refcnt_lock and don't remove the node from nodehash here.
* nfs/cache.c (netfs_try_dropping_softrefs): Drop the light reference
when the node has no more hard references.
* nfs/cache.c (recache_handle): Use nodehash_ihash_lock instead.
* nfs/ops.c (netds_attempt_unlink): Use refcounts_references.
* console/console.c (netfs_node_norefs): Use a soft reference to store
a node in dir_node, cons_node, disp_node, inp_node.
* console/console.c (netfs_try_dropping_softrefs): When dropping all
soft references remove node pointer from the fields above.
Diffstat (limited to 'console')
-rw-r--r-- | console/console.c | 64 |
1 files changed, 37 insertions, 27 deletions
diff --git a/console/console.c b/console/console.c index 57ae8133..9c5869dd 100644 --- a/console/console.c +++ b/console/console.c @@ -415,47 +415,51 @@ new_node (struct node **np, vcons_t vcons, vcons_node_type type) /* Node management. */ -/* Node NP has no more references; free all its associated - storage. */ +/* We need to drop the soft references on NP. */ void -netfs_node_norefs (struct node *np) +netfs_try_dropping_softrefs (struct node *np) { vcons_t vcons = np->nn->vcons; + int release = FALSE; - /* The root node does never go away. */ - assert (!np->nn->cons && np->nn->vcons); - - /* Avoid deadlock. */ - pthread_spin_unlock (&netfs_node_refcnt_lock); - - /* Find the back reference to ourself in the virtual console - structure, and delete it. */ pthread_mutex_lock (&vcons->lock); - pthread_spin_lock (&netfs_node_refcnt_lock); - if (np->references) + if (np == vcons->dir_node) { - /* Someone else got a reference while we were attempting to go - away. This can happen in netfs_attempt_lookup. In this - case, just unlock the node and do nothing else. */ - pthread_mutex_unlock (&vcons->lock); - pthread_mutex_unlock (&np->lock); - return; + release = TRUE; + vcons->dir_node = 0; } - if (np == vcons->dir_node) - vcons->dir_node = 0; else if (np == vcons->cons_node) - vcons->cons_node = 0; + { + release = TRUE; + vcons->cons_node = 0; + } else if (np == vcons->disp_node) - vcons->disp_node = 0; - else { - assert (np == vcons->inpt_node); + release = TRUE; + vcons->disp_node = 0; + } + else if (np == vcons->inpt_node) + { + release = TRUE; vcons->inpt_node = 0; } + if (release) + netfs_nrele_light (np); pthread_mutex_unlock (&vcons->lock); /* Release our reference. */ - vcons_release (vcons); + if (release) + vcons_release (vcons); + +} + +/* Node NP has no more references; free all its associated + storage. */ +void +netfs_node_norefs (struct node *np) +{ + /* The root node does never go away. */ + assert (!np->nn->cons && np->nn->vcons); free (np->nn); free (np); @@ -634,7 +638,10 @@ netfs_attempt_lookup (struct iouser *user, struct node *dir, the virtual console. */ err = new_node (node, vcons, VCONS_NODE_DIR); if (!err) - vcons->dir_node = *node; + { + vcons->dir_node = *node; + netfs_nref_light (*node); + } else release_vcons = 1; } @@ -663,6 +670,7 @@ netfs_attempt_lookup (struct iouser *user, struct node *dir, if (!err) { vcons->cons_node = *node; + netfs_nref_light (*node); ref_vcons = 1; } } @@ -682,6 +690,7 @@ netfs_attempt_lookup (struct iouser *user, struct node *dir, if (!err) { vcons->disp_node = *node; + netfs_nref_light (*node); ref_vcons = 1; } } @@ -701,6 +710,7 @@ netfs_attempt_lookup (struct iouser *user, struct node *dir, if (!err) { vcons->inpt_node = *node; + netfs_nref_light (*node); ref_vcons = 1; } } |