Formerly ../hurd/hurd/port.h.~2~
authorroland <roland>
Fri, 28 Jan 1994 08:20:00 +0000 (08:20 +0000)
committerroland <roland>
Fri, 28 Jan 1994 08:20:00 +0000 (08:20 +0000)
hurd/hurd/port.h

index 2be9723..5b486f0 100644 (file)
@@ -23,6 +23,7 @@ Cambridge, MA 02139, USA.  */
 #include <features.h>
 
 #include <mach/mach_port.h>
+#include <hurd/userlink.h>
 
 
 /* Structure describing a cell containing a port.  With the lock held, a
@@ -30,33 +31,31 @@ Cambridge, MA 02139, USA.  */
    USERS chain.  PORT can then safely be used.  When PORT is no longer
    needed, with the lock held, the user removes his link from the chain.
    If his link is the last, and PORT has changed since he fetched it, the
-   user deallocates the port he used.  */
+   user deallocates the port he used.  See <hurd/userlink.h>.  */
+
 struct hurd_port
   {
 #ifdef noteven
     spin_lock_t lock;          /* Locks rest.  */
 #endif
-    struct hurd_port_userlink *users; /* Chain of users; see below.  */
+    struct hurd_userlink *users; /* Chain of users; see below.  */
     mach_port_t port;          /* Port. */
   };
 
-/* This structure is simply a doubly-linked list.
-   Users of a port cell are recorded by their presence in the list.  */   
-struct hurd_port_userlink
-  {
-    struct hurd_port_userlink *next, **prevp;
-  };
 
 /* Evaluate EXPR with the variable `port' bound to the port in PORTCELL.  */
+
 #define        HURD_PORT_USE(portcell, expr)                                         \
   ({ struct _hurd_port *const __p = (portcell);                                      \
-     struct _hurd_port_userlink __link;                                              \
+     struct _hurd_userlink __link;                                           \
      const mach_port_t port = _hurd_port_get (__p, &__link);                 \
      __typeof(expr) __result = (expr);                                       \
      _hurd_port_free (__p, &__link, port);                                   \
      __result; })
 
+
 /* Initialize *PORT to INIT.  */
+
 extern inline void
 _hurd_port_init (struct hurd_port *port, mach_port_t init)
 {
@@ -67,74 +66,57 @@ _hurd_port_init (struct hurd_port *port, mach_port_t init)
   port->port = init;
 }
 
+
 /* Get a reference to *PORT, which is locked.
    Pass return value and LINK to _hurd_port_free when done.  */
+
 extern inline mach_port_t
 _hurd_port_locked_get (struct hurd_port *port,
-                      struct hurd_port_userlink *link)
+                      struct hurd_userlink *link)
 {
   mach_port_t result;
   result = port->port;
   if (result != MACH_PORT_NULL)
-    {
-      link->next = port->users;
-      if (link->next)
-       link->next->prevp = &link->next;
-      link->prevp = &port->users;
-      port->users = link;
-    }
+    _hurd_userlink_link (&port->users, link);
   __spin_unlock (&port->lock);
   return result;
 }
 
 /* Same, but locks PORT first.  */
+
 extern inline mach_port_t
 _hurd_port_get (struct hurd_port *port,
-               struct hurd_port_userlink *link)
+               struct hurd_userlink *link)
 {
   __spin_lock (&port->lock);
   return _hurd_port_locked_get (port, link);
 }
 
-/* Free a reference gotten with
-   `USED_PORT = _hurd_port_get (PORT, LINK);' */
+
+/* Free a reference gotten with `USED_PORT = _hurd_port_get (PORT, LINK);' */
+
 extern inline void
 _hurd_port_free (struct hurd_port *port,
-                struct hurd_port_userlink *link,
+                struct hurd_userlink *link,
                 mach_port_t used_port)
 {
   int dealloc;
   __spin_lock (&port->lock);
-  /* We should deallocate USED_PORT if our chain has been detached from the
-     cell (and thus has a nil `prevp'), and there is no next link
-     representing another user reference to the same port we fetched.  */
-  dealloc = ! link->next && ! link->prevp;
-  /* Remove our link from the chain of current users.  */
-  if (link->prevp)
-    *link->prevp = link->next;
-  if (link->next)
-    link->next->prevp = link->prevp;
+  dealloc = _hurd_userlink_unlink (link);
   __spin_unlock (&port->lock);
   if (dealloc)
     __mach_port_deallocate (__mach_task_self (), used_port);
 }
 
+
 /* Set *PORT's port to NEWPORT.  NEWPORT's reference is consumed by PORT->port.
    PORT->lock is locked.  */
+
 extern inline void
 _hurd_port_locked_set (struct hurd_port *port, mach_port_t newport)
 {
   mach_port_t old;
-  if (port->users == NULL)
-    old = port->port;
-  else
-    {
-      old = MACH_PORT_NULL;
-      /* Detach the chain of current users from the cell.  The last user to
-        remove his link from that chain will deallocate the old port.  */
-      port->users->prevp = NULL;
-      port->users = NULL;
-    }
+  old = _hurd_userlink_clear (&port->users) ? port->port : MACH_PORT_NULL;
   port->port = newport;
   __spin_unlock (&port->lock);
   if (old != MACH_PORT_NULL)
@@ -142,6 +124,7 @@ _hurd_port_locked_set (struct hurd_port *port, mach_port_t newport)
 }
 
 /* Same, but locks PORT first.  */
+
 extern inline void
 _hurd_port_set (struct hurd_port *port, mach_port_t newport)
 {