Exemplo n.º 1
0
mach_port_t
ports_claim_right (void *portstruct)
{
  error_t err;
  struct port_info *pi = portstruct;
  mach_port_t ret = pi->port_right;

  if (ret == MACH_PORT_NULL)
    return ret;

  pthread_rwlock_wrlock (&_ports_htable_lock);
  hurd_ihash_locp_remove (&_ports_htable, pi->ports_htable_entry);
  hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry);
  pthread_rwlock_unlock (&_ports_htable_lock);
  err = mach_port_move_member (mach_task_self (), ret, MACH_PORT_NULL);
  assert_perror (err);
  pthread_mutex_lock (&_ports_lock);
  pi->port_right = MACH_PORT_NULL;
  if (pi->flags & PORT_HAS_SENDRIGHTS)
    {
      pi->flags &= ~PORT_HAS_SENDRIGHTS;
      pthread_mutex_unlock (&_ports_lock);
      ports_port_deref (pi);
    }
  else
    pthread_mutex_unlock (&_ports_lock);

  return ret;
}
Exemplo n.º 2
0
/* Change the file handle used for node NP to be the handle at P.
   Make sure the hash table stays up to date.  Return the address
   after the handle.  The lock on the node should be held.  */
int *
recache_handle (int *p, struct node *np)
{
  size_t len;

  if (protocol_version == 2)
    len = NFS2_FHSIZE;
  else
    {
      len = ntohl (*p);
      p++;
    }
  
  /* Unlink it */
  pthread_mutex_lock (&nodehash_ihash_lock);
  hurd_ihash_locp_remove (&nodehash, np->nn->slot);

  /* Change the name */
  np->nn->handle.size = len;
  memcpy (np->nn->handle.data, p, len);
  
  /* Reinsert it */
  hurd_ihash_add (&nodehash, (hurd_ihash_key_t) &np->nn->handle, np);
  
  pthread_mutex_unlock (&nodehash_ihash_lock);
  return p + len / sizeof (int);
}
Exemplo n.º 3
0
/* When dropping soft refs, we simply remove the node from the
   node cache.  */
void
netfs_try_dropping_softrefs (struct node *np)
{
  pthread_mutex_lock (&nodehash_ihash_lock);
  hurd_ihash_locp_remove (&nodehash, np->nn->slot);
  netfs_nrele_light (np);
  pthread_mutex_unlock (&nodehash_ihash_lock);
}
Exemplo n.º 4
0
error_t
ports_transfer_right (void *tostruct, 
		      void *fromstruct)
{
  struct port_info *topi = tostruct;
  struct port_info *frompi = fromstruct;
  mach_port_t port;
  int dereffrompi = 0;
  int dereftopi = 0;
  int hassendrights = 0;
  error_t err;

  mutex_lock (&_ports_lock);

  /* Fetch the port in FROMPI and clear its use */
  port = frompi->port_right;
  if (port != MACH_PORT_NULL)
    {
      hurd_ihash_locp_remove (&frompi->bucket->htable, frompi->hentry);
      frompi->port_right = MACH_PORT_NULL;
      if (frompi->flags & PORT_HAS_SENDRIGHTS)
	{
	  frompi->flags &= ~PORT_HAS_SENDRIGHTS;
	  hassendrights = 1;
	  dereffrompi = 1;
	}
    }
  
  /* Destroy the existing right in TOPI. */
  if (topi->port_right != MACH_PORT_NULL)
    {
      hurd_ihash_locp_remove (&topi->bucket->htable, topi->hentry);
      err = mach_port_mod_refs (mach_task_self (), topi->port_right,
				MACH_PORT_RIGHT_RECEIVE, -1);
      assert_perror (err);
      if ((topi->flags & PORT_HAS_SENDRIGHTS) && !hassendrights)
	{
	  dereftopi = 1;
	  topi->flags &= ~PORT_HAS_SENDRIGHTS;
	}
      else if (((topi->flags & PORT_HAS_SENDRIGHTS) == 0) && hassendrights)
	{
	  topi->flags |= PORT_HAS_SENDRIGHTS;
	  topi->refcnt++;
	}
    }
  
  /* Install the new right in TOPI. */
  topi->port_right = port;
  topi->cancel_threshold = frompi->cancel_threshold;
  topi->mscount = frompi->mscount;
  
  if (port)
    {
      hurd_ihash_add (&topi->bucket->htable, port, topi);
      if (topi->bucket != frompi->bucket)
        {
	  err = mach_port_move_member (mach_task_self (), port,
				       topi->bucket->portset);
	  assert_perror (err);
	}
    }
  
  mutex_unlock (&_ports_lock);
  
  /* Take care of any lowered reference counts. */
  if (dereffrompi)
    ports_port_deref (frompi);
  if (dereftopi)
    ports_port_deref (topi);
  return 0;
}