/* * Lookup by hostname for an onion entry in a given pool. The entry is returned * if found or else a new one is created, added to the pool and finally * returned. * * NOTE: The pool lock MUST NOT be acquired before calling this. * * On success the entry is returned else a NULL value. */ static struct onion_entry *get_onion_entry(const char *hostname, struct onion_pool *pool) { struct onion_entry *entry = NULL; assert(hostname); assert(pool); tsocks_mutex_lock(&pool->lock); entry = onion_entry_find_by_name(hostname, pool); if (entry) { goto end; } /* * On success, the onion entry is automatically added to the onion pool and * the reference is returned. */ entry = onion_entry_create(pool, hostname); if (!entry) { goto error; } end: error: tsocks_mutex_unlock(&pool->lock); return entry; }
/* * Call the given routine once, and only once. tsocks_once returning * guarantees that the routine has succeded. */ void tsocks_once(tsocks_once_t *o, void (*init_routine)(void)) { /* Why, yes, pthread_once(3P) exists. Said routine requires linking in a * real pthread library on Linux, while this does not and will do the right * thing even with the stub implementation. */ assert(o); /* This looks scary and incorrect, till you realize that the * pthread_mutex routines include memory barriers. */ if (!o->once) { return; } tsocks_mutex_lock(&o->mutex); if (o->once) { init_routine(); o->once = 0; } tsocks_mutex_unlock(&o->mutex); }