* libtrivfs/trivfs.h (struct trivfs_peropen): Use refcount_t for field refcnt. (struct trivfs_control): Remove unused field lock. * libtrivfs/cntl-create.c (trivfs_create_control): Drop the mutex initialization. * libtrivfs/io-reauthenticate.c (trivfs_S_io_reauthenticate): Adjust accordingly. * libtrivfs/io-restrict-auth.c (trivfs_S_io_restrict_auth): Likewise. * libtrivfs/open.c (trivfs_open): Initialize refcnt. * libtrivfs/protid-clean.c (trivfs_clean_protid): Likewise. * libtrivfs/protid-dup.c (trivfs_protid_dup): Likewise. --- libtrivfs/cntl-create.c | 1 - libtrivfs/io-reauthenticate.c | 5 +---- libtrivfs/io-restrict-auth.c | 4 +--- libtrivfs/open.c | 2 +- libtrivfs/protid-clean.c | 26 +++++++++++++++----------- libtrivfs/protid-dup.c | 5 +---- libtrivfs/trivfs.h | 4 ++-- 7 files changed, 21 insertions(+), 26 deletions(-)
diff --git a/libtrivfs/cntl-create.c b/libtrivfs/cntl-create.c index 910daf3..eb9a834 100644 --- a/libtrivfs/cntl-create.c +++ b/libtrivfs/cntl-create.c @@ -85,7 +85,6 @@ trivfs_create_control (mach_port_t underlying, } (*control)->hook = 0; - pthread_mutex_init (&(*control)->lock, NULL); } out: diff --git a/libtrivfs/io-reauthenticate.c b/libtrivfs/io-reauthenticate.c index 7677697..df0ed2e 100644 --- a/libtrivfs/io-reauthenticate.c +++ b/libtrivfs/io-reauthenticate.c @@ -62,11 +62,8 @@ trivfs_S_io_reauthenticate (struct trivfs_protid *cred, newcred->isroot = 1; newcred->hook = cred->hook; - - pthread_mutex_lock (&cred->po->cntl->lock); newcred->po = cred->po; - newcred->po->refcnt++; - pthread_mutex_unlock (&cred->po->cntl->lock); + refcount_ref (&newcred->po->refcnt); do err = io_restrict_auth (newcred->po->cntl->underlying, &newcred->realnode, diff --git a/libtrivfs/io-restrict-auth.c b/libtrivfs/io-restrict-auth.c index 65b4fd6..39670fe 100644 --- a/libtrivfs/io-restrict-auth.c +++ b/libtrivfs/io-restrict-auth.c @@ -110,10 +110,8 @@ trivfs_S_io_restrict_auth (struct trivfs_protid *cred, } newcred->isroot = 0; - pthread_mutex_lock (&cred->po->cntl->lock); newcred->po = cred->po; - newcred->po->refcnt++; - pthread_mutex_unlock (&cred->po->cntl->lock); + refcount_ref (&newcred->po->refcnt); if (cred->isroot && idvec_contains (user->uids, 0)) newcred->isroot = 1; newcred->user = user; diff --git a/libtrivfs/open.c b/libtrivfs/open.c index f64d2ff..97e70a1 100644 --- a/libtrivfs/open.c +++ b/libtrivfs/open.c @@ -40,7 +40,7 @@ trivfs_open (struct trivfs_control *cntl, ports_port_ref (cntl); - po->refcnt = 1; + refcount_init (&po->refcnt, 1); po->cntl = cntl; po->openmodes = flags; po->hook = 0; diff --git a/libtrivfs/protid-clean.c b/libtrivfs/protid-clean.c index f98da6a..cce736d 100644 --- a/libtrivfs/protid-clean.c +++ b/libtrivfs/protid-clean.c @@ -31,19 +31,23 @@ trivfs_clean_protid (void *arg) (*trivfs_protid_destroy_hook) (cred); /* If we hold the only reference to the peropen, try to get rid of it. */ - pthread_mutex_lock (&cntl->lock); - if (cred->po->refcnt == 1 && trivfs_peropen_destroy_hook) + if (refcount_deref (&cred->po->refcnt) == 0) { - pthread_mutex_unlock (&cntl->lock); - (*trivfs_peropen_destroy_hook) (cred->po); - pthread_mutex_lock (&cntl->lock); + if (trivfs_peropen_destroy_hook) + { + /* Reaquire a reference while we call the hook. */ + refcount_ref (&cred->po->refcnt); + (*trivfs_peropen_destroy_hook) (cred->po); + if (refcount_deref (&cred->po->refcnt) == 0) + goto free_po; + } + else + { + free_po: + ports_port_deref (cntl); + free (cred->po); + } } - if (--cred->po->refcnt == 0) - { - ports_port_deref (cntl); - free (cred->po); - } - pthread_mutex_unlock (&cntl->lock); iohelp_free_iouser (cred->user); diff --git a/libtrivfs/protid-dup.c b/libtrivfs/protid-dup.c index 6169603..75f3ca8 100644 --- a/libtrivfs/protid-dup.c +++ b/libtrivfs/protid-dup.c @@ -35,11 +35,8 @@ trivfs_protid_dup (struct trivfs_protid *cred, struct trivfs_protid **dup) if (! err) { - pthread_mutex_lock (&cred->po->cntl->lock); new->po = cred->po; - new->po->refcnt++; - pthread_mutex_unlock (&cred->po->cntl->lock); - + refcount_ref (&new->po->refcnt); new->isroot = cred->isroot; err = iohelp_dup_iouser (&new->user, cred->user); diff --git a/libtrivfs/trivfs.h b/libtrivfs/trivfs.h index bb456ff..8902338 100644 --- a/libtrivfs/trivfs.h +++ b/libtrivfs/trivfs.h @@ -24,6 +24,7 @@ #include <mach/mach.h> #include <hurd/ports.h> #include <hurd/iohelp.h> +#include <refcount.h> struct trivfs_protid { @@ -41,14 +42,13 @@ struct trivfs_peropen { void *hook; /* for user use */ int openmodes; - int refcnt; + refcount_t refcnt; struct trivfs_control *cntl; }; struct trivfs_control { struct port_info pi; - pthread_mutex_t lock; struct port_class *protid_class; struct port_bucket *protid_bucket; mach_port_t filesys_id; -- 2.0.0.rc0