void __pthread_destroy_specific (struct __pthread *thread) { error_t err; int i; int seen_one; /* Check if there is any thread specific data. */ if (! thread->thread_specifics) return; __pthread_key_lock_ready (); /* Iterate and call the destructors on any thread specific data. */ for (;;) { seen_one = 0; __pthread_mutex_lock (&__pthread_key_lock); for (i = 0; i < __pthread_key_count; i ++) { void *value; if (__pthread_key_destructors[i] == PTHREAD_KEY_INVALID) continue; value = hurd_ihash_find (thread->thread_specifics, i); if (value) { err = hurd_ihash_remove (thread->thread_specifics, i); assert (err == 1); if (__pthread_key_destructors[i]) { seen_one = 1; __pthread_key_destructors[i] (value); } } } __pthread_mutex_unlock (&__pthread_key_lock); if (! seen_one) break; /* This may take a very long time. Let those blocking on pthread_key_create or pthread_key_delete make progress. */ sched_yield (); } hurd_ihash_free (thread->thread_specifics); thread->thread_specifics = 0; }
/** @brief get thread specific value base key */ void *pthread_getspecific(pthread_key_t key) { 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 NULL; /* not exist, immedily exit */ if (!speci_tb) return NULL; /* find value */ return hurd_ihash_find(speci_tb, (hurd_ihash_key_t)key); }
/* 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; }