/* Lightweight user references for ports.
   Copyright (C) 1993, 1994, 1995, 1997, 1999, 2007
   Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#ifndef	_HURD_PORT_H

#define	_HURD_PORT_H	1
#include <features.h>

#include <mach.h>
#include <hurd/userlink.h>
#include <spin-lock.h>
#include <hurd/signal.h>


/* Structure describing a cell containing a port.  With the lock held, a
   user extracts PORT, and attaches his own link (in local storage) to the
   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.  See <hurd/userlink.h>.  */

struct hurd_port
  {
    spin_lock_t lock;		/* Locks rest.  */
    struct hurd_userlink *users; /* Chain of users; see below.  */
    mach_port_t port;		/* Port. */
  };


/* 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_userlink __link;					      \
     const mach_port_t port = _hurd_port_get (__p, &__link);		      \
     __typeof(expr) __result = (expr);					      \
     _hurd_port_free (__p, &__link, port);				      \
     __result; })


#ifndef _HURD_PORT_H_EXTERN_INLINE
#define _HURD_PORT_H_EXTERN_INLINE __extern_inline
#endif


/* Initialize *PORT to INIT.  */

_HURD_PORT_H_EXTERN_INLINE void
_hurd_port_init (struct hurd_port *port, mach_port_t init)
{
  __spin_lock_init (&port->lock);
  port->users = NULL;
  port->port = init;
}


/* Cleanup function for non-local exits.  */
extern void _hurd_port_cleanup (void *, jmp_buf, int);

/* Get a reference to *PORT, which is locked.
   Pass return value and LINK to _hurd_port_free when done.  */

_HURD_PORT_H_EXTERN_INLINE mach_port_t
_hurd_port_locked_get (struct hurd_port *port,
		       struct hurd_userlink *link)
{
  mach_port_t result;
  result = port->port;
  if (result != MACH_PORT_NULL)
    {
      link->cleanup = &_hurd_port_cleanup;
      link->cleanup_data = (void *) result;
      _hurd_userlink_link (&port->users, link);
    }
  __spin_unlock (&port->lock);
  return result;
}

/* Same, but locks PORT first.  */

_HURD_PORT_H_EXTERN_INLINE mach_port_t
_hurd_port_get (struct hurd_port *port,
		struct hurd_userlink *link)
{
  mach_port_t result;
  HURD_CRITICAL_BEGIN;
  __spin_lock (&port->lock);
  result = _hurd_port_locked_get (port, link);
  HURD_CRITICAL_END;
  return result;
}


/* Free a reference gotten with `USED_PORT = _hurd_port_get (PORT, LINK);' */

_HURD_PORT_H_EXTERN_INLINE void
_hurd_port_free (struct hurd_port *port,
		 struct hurd_userlink *link,
		 mach_port_t used_port)
{
  int dealloc;
  if (used_port == MACH_PORT_NULL)
    /* When we fetch an empty port cell with _hurd_port_get,
       it does not link us on the users chain, since there is
       no shared resource.  */
    return;
  HURD_CRITICAL_BEGIN;
  __spin_lock (&port->lock);
  dealloc = _hurd_userlink_unlink (link);
  __spin_unlock (&port->lock);
  HURD_CRITICAL_END;
  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.  */

_HURD_PORT_H_EXTERN_INLINE void
_hurd_port_locked_set (struct hurd_port *port, mach_port_t newport)
{
  mach_port_t old;
  old = _hurd_userlink_clear (&port->users) ? port->port : MACH_PORT_NULL;
  port->port = newport;
  __spin_unlock (&port->lock);
  if (old != MACH_PORT_NULL)
    __mach_port_deallocate (__mach_task_self (), old);
}

/* Same, but locks PORT first.  */

_HURD_PORT_H_EXTERN_INLINE void
_hurd_port_set (struct hurd_port *port, mach_port_t newport)
{
  HURD_CRITICAL_BEGIN;
  __spin_lock (&port->lock);
  _hurd_port_locked_set (port, newport);
  HURD_CRITICAL_END;
}


#endif	/* hurd/port.h */
