bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 06/11] libtrivfs: lock-less reference counting for trivfs_peropen


From: Justus Winter
Subject: [PATCH 06/11] libtrivfs: lock-less reference counting for trivfs_peropen objects
Date: Mon, 12 May 2014 12:05:44 +0200

* 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]