From 1d1da90042d2ee7a8215dc6291b54bc1ebe59fe4 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Tue, 6 May 2014 19:07:13 +0200 Subject: libtrivfs: lock-less reference counting for trivfs_peropen objects * 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/protid-clean.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'libtrivfs/protid-clean.c') diff --git a/libtrivfs/protid-clean.c b/libtrivfs/protid-clean.c index f98da6a5..86fbc191 100644 --- a/libtrivfs/protid-clean.c +++ b/libtrivfs/protid-clean.c @@ -31,19 +31,26 @@ 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 (trivfs_peropen_destroy_hook) { - pthread_mutex_unlock (&cntl->lock); - (*trivfs_peropen_destroy_hook) (cred->po); - pthread_mutex_lock (&cntl->lock); + if (refcount_deref (&cred->po->refcnt) == 0) + { + /* 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) + { + ports_port_deref (cntl); + free (cred->po); + } + } } - if (--cred->po->refcnt == 0) - { - ports_port_deref (cntl); - free (cred->po); - } - pthread_mutex_unlock (&cntl->lock); + else + if (refcount_deref (&cred->po->refcnt) == 0) + { + ports_port_deref (cntl); + free (cred->po); + } iohelp_free_iouser (cred->user); -- cgit v1.2.3