Beispiel #1
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);
}
Beispiel #2
0
/**
	@brief This function set value to thread_specific data by the key.
*/
int pthread_setspecific (pthread_key_t key, const void *value)
{
    hurd_ihash_t speci_tb = (hurd_ihash_t)get_current_pt_specific();

    /* key is valid ? */
    if (key > __pthread_key_nums ||
            __destructort_arry[key] == DESTRUCTORT_INVALID)
        return -EINVAL;

    /* has created? */
    if (!speci_tb)
    {
        int ret;

        /* if failt, it must out of memory */
        if (hurd_ihash_create(&speci_tb, HURD_IHASH_NO_LOCP) != 0)
            return -ENOMEM;

        /* add speci_tb to speci_tables */
        pthread_spin_lock(&__pthread_specific_lock);
        ret = find_elem_index_and_add_to_arry(speci_tb, &__pthread_specific_arry, (int *)&__pthread_specific_nums, NULL);
        pthread_spin_unlock(&__pthread_specific_lock);

        /* errno is always no mem */
        if (ret < 0)
        {
            hurd_ihash_destroy(speci_tb);
            return -ENOMEM;
        }

        /* set to pthread */
        set_current_pt_specific((void *)speci_tb);
    }

    /* add to ihash tables */
    if (hurd_ihash_add(speci_tb, (hurd_ihash_key_t)key, (hurd_ihash_value_t)value) != 0)
        return -ENOMEM;

    return 0;
}
Beispiel #3
0
int
pthread_setspecific (pthread_key_t key, const void *value)
{
  error_t err;
  struct __pthread *self = _pthread_self ();

  if (key < 0 || key >= __pthread_key_count
      || __pthread_key_destructors[key] == PTHREAD_KEY_INVALID)
    return EINVAL;

  if (! self->thread_specifics)
    {
      err = hurd_ihash_create (&self->thread_specifics, HURD_IHASH_NO_LOCP);
      if (err)
	return ENOMEM;
    }

  err = hurd_ihash_add (self->thread_specifics, key, (void *) value);
  if (err)
    return ENOMEM;

  return 0;
}
Beispiel #4
0
/* Lookup the file handle HANDLE in the hash table.  If it is
   not present, initialize a new node structure and insert it into the
   hash table.  Whichever course, a new reference is generated and the
   node is returned in *NPP; the lock on the node, (*NPP)->LOCK, is
   held.  */
void
lookup_fhandle (struct fhandle *handle, struct node **npp)
{
  struct node *np;
  struct netnode *nn;

  pthread_mutex_lock (&nodehash_ihash_lock);
  np = hurd_ihash_find (&nodehash, (hurd_ihash_key_t) handle);
  if (np)
    {
      netfs_nref (np);
      pthread_mutex_unlock (&nodehash_ihash_lock);
      pthread_mutex_lock (&np->lock);
      *npp = np;
      return;
    }
  
  /* Could not find it */
  np = netfs_make_node_alloc (sizeof (struct netnode));
  assert (np);
  nn = netfs_node_netnode (np);

  nn->handle.size = handle->size;
  memcpy (nn->handle.data, handle->data, handle->size);
  nn->stat_updated = 0;
  nn->dtrans = NOT_POSSIBLE;
  nn->dead_dir = 0;
  nn->dead_name = 0;
  
  hurd_ihash_add (&nodehash, (hurd_ihash_key_t) &nn->handle, np);
  netfs_nref_light (np);
  pthread_mutex_unlock (&nodehash_ihash_lock);
  pthread_mutex_lock (&np->lock);
  
  *npp = np;
}
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;
}