/* the agent is now a separate thread */ void * server_agent(void *params) { int client_fd, n, errcode; enum header_types type; unsigned int len; char to_search[MAX_SEARCH_STR]; char remote_obj[REMOTE_NAME_MAX]; time_type t_start, t_end; double tdiff; msg_one msg1; search *mysearch; Statistics statistic; /* we are now successfully connected to a remote client */ client_fd = ((struct thread_params *) params)->client_fd; fprintf(stderr, "Starting Agent fd: %d, thread id: %lu \n", client_fd, (unsigned long) pthread_self()); /* do some initialization*/ memset(&statistic, 0, sizeof(Statistics)); errcode = pthread_detach(pthread_self()); if (errcode != 0) { fprintf(stderr, "pthread_detach server agent: %s\n", strerror(errcode)); } pthread_once(&init_done, thread_init); get_time(&t_start); len = sizeof(msg_one); /* first message should be the file name */ if ((n = our_recv_message(client_fd, &type, &len, &msg1)) < 0) return NULL; if (type != OPTION_PARAMETER) return NULL; /*firstly build the search object */ mysearch = build_search(&msg1); mysearch->client_fd = client_fd; /* then print the search options */ print_search_para(client_fd, mysearch); /* receive the second message*/ len = MAX_SEARCH_STR; if ((n = our_recv_message(client_fd, &type, &len, to_search)) < 0) return NULL; if (type != TO_SEARCH) return NULL; len = strlen(to_search); if ((mysearch->search_pattern = (char*) malloc(len + 1)) == NULL) { perror("malloc"); free(params); return NULL; } strncpy(mysearch->search_pattern, to_search, len+1); /*build its own shift table if needed */ build_shifttable(mysearch); /* receive the second message*/ len = REMOTE_NAME_MAX; if ((n = our_recv_message(client_fd, &type, &len, remote_obj)) < 0) return NULL; if (type != REMOTE_NAME) return NULL; /* do the search job */ search_given(remote_obj, mysearch); /* send the statistics message 6*/ /*wait for directory search to be finished if it is on the server side*/ while (mysearch->stk_count != 0) { pthread_cond_wait(&(mysearch->ready), &(mysearch->lock)); } len = sizeof(Statistics); /* make a copy of little/big endian adapted statistical structure*/ update_statistics_sock(&statistic, &mysearch->statistics); trans_stat2send(&statistic); if (our_send_message(mysearch->client_fd, STATISTICS_MSG, len, &statistic) != 0) { fprintf(stderr, "Fail to send statistics\n"); return NULL; } get_time(&t_end); tdiff = time_diff(&t_start, &t_end); fprintf(stderr, "Search Statistics: client fd %u, thread id %lu\n", mysearch->client_fd, (unsigned long) pthread_self()); print_stat(stderr, &mysearch->statistics, tdiff); destroy_search(mysearch); fprintf(stderr, "Terminating Agent fd: %d, thread id: %lu \n", client_fd, (unsigned long) pthread_self()); free(params); return NULL; } /* server_agent */
static void __Unwind_SjLj_SetTopOfFunctionStack(struct _Unwind_FunctionContext* fc) { pthread_once(&sOnceFlag, __Unwind_SjLj_MakeTopOfFunctionStackKey); pthread_setspecific(sPerThreadTopOfFunctionStack, fc); }
sem_t * semcompat_new( int pshared, unsigned int value) { sem_t * ret; int errno_save; if (pthread_once(&support_unnamed_initialized, initialize_support_unnamed) != 0) { // errno is set by pthread_once return SEM_FAILED; } if (support_unnamed) { ret = malloc(sizeof(sem_t)); if (ret == NULL) { // errno is set by malloc return SEM_FAILED; } if (sem_init(ret, pshared, value) != 0) { errno_save = errno; free(ret); errno = errno_save; return SEM_FAILED; } return ret; } else { size_t i; char name[SEM_NAME_SIZE]; for (i = 0; i < SEM_OPEN_MAX_TRIES; ++i) { make_sem_name(name); ret = sem_open(name, O_CREAT | O_EXCL, 0600, value); if (ret == SEM_FAILED) { if (errno == EEXIST) { // try another name continue; } else { // errno is set by sem_open return SEM_FAILED; } } else { // Now that it's open, we don't want any other processes to // access it by name. if (sem_unlink(name) != 0) { LOG(LOG_WARNING, "failed to unlink semaphore %s, continuing anyway", name); } return ret; } } LOG(LOG_ERR, "failed to create a semaphore after %d tries", SEM_OPEN_MAX_TRIES); errno = EAGAIN; return SEM_FAILED; } }
static OSStatus BindReplyMachPortToThread(mach_port_t *replyPortPtr) // Get a reply port for this thread, remembering that we've done this // in per-thread storage. // // On success, *replyPortPtr is the port to use for this thread's reply // port. It will be MACH_PORT_NULL if you call it from the main thread. { OSStatus err; assert( replyPortPtr != NULL); assert(*replyPortPtr == MACH_PORT_NULL); // Initialise ourselves the first time that we're called. err = (OSStatus) pthread_once(&sInited, InitRoutine); // If something went wrong, return the latched error. if ( (err == noErr) && (sPerThreadStorageKeyInitErrNum != noErr) ) { err = sPerThreadStorageKeyInitErrNum; } // Now do the real work. if (err == noErr) { if ( pthread_main_np() ) { // This is the main thread, so do nothing; leave *replyPortPtr set // to MACH_PORT_NULL. assert(*replyPortPtr == MACH_PORT_NULL); } else { PerThreadStorage * storage; // Get the per-thread storage for this thread. storage = (PerThreadStorage *) pthread_getspecific(sPerThreadStorageKey); if (storage == NULL) { // The per-thread storage hasn't been allocated yet for this specific // thread. Let's go allocate it and attach it to this thread. err = AllocatePortFromPool(&storage); if (err == noErr) { err = (OSStatus) pthread_setspecific(sPerThreadStorageKey, (void *) storage); if (err != noErr) { ReturnPortToPool(storage); storage = NULL; } } } assert( (err == noErr) == (storage != NULL) ); // If all went well, copy the port out to our client. if (err == noErr) { assert(storage->magic == kPerThreadStorageMagic); assert(storage->port != MACH_PORT_NULL); *replyPortPtr = storage->port; } } } // no error + MACH_PORT_NULL is a valid response if we're on the main // thread. // // assert( (err == noErr) == (*replyPortPtr != MACH_PORT_NULL) ); assert( (*replyPortPtr == MACH_PORT_NULL) || (err == noErr) ); return err; }
void xeno_sigshadow_install_once(void) { static pthread_once_t sigshadow_installed = PTHREAD_ONCE_INIT; pthread_once(&sigshadow_installed, xeno_sigshadow_install); }
static inline void s_init(void) { (void)pthread_once(&s_once, s_once_proc); }
void cobalt_init_umm(__u32 vdso_offset) { pthread_once(&init_bind_once, init_bind); init_loadup(vdso_offset); }
static long CallSimultaneously(u_int threads, opaque rock, long (*proc)(int, opaque)) { long code; int i; #ifdef AFS_PTHREAD_ENV pthread_once(&workerOnce, WorkerInit); #endif workers = 0; for (i = 0; i < threads; i++) { struct worker *w; #ifdef AFS_PTHREAD_ENV pthread_t pid; #else PROCESS pid; #endif assert(i < MAX_CTHREADS); w = (struct worker *)osi_Alloc(sizeof(struct worker)); memset(w, 0, sizeof(*w)); w->next = workers; workers = w; w->index = i; w->exitCode = RXKST_PROCESSRUNNING; w->rock = rock; w->proc = proc; #ifdef AFS_PTHREAD_ENV { pthread_attr_t tattr; code = pthread_attr_init(&tattr); if (code) { afs_com_err(whoami, code, "can't pthread_attr_init worker process"); return code; } code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) { afs_com_err(whoami, code, "can't pthread_attr_setdetachstate worker process"); return code; } code = pthread_create(&pid, &tattr, DoWorker, (void *)w); } #else code = LWP_CreateProcess(DoWorker, 16000, LWP_NORMAL_PRIORITY, (opaque) w, "Worker Process", &pid); #endif if (code) { afs_com_err(whoami, code, "can't create worker process"); return code; } } code = 0; /* last non-zero code encountered */ #ifdef AFS_PTHREAD_ENV pthread_mutex_lock(&workerLock); #endif while (workers) { struct worker *w, *prevW, *nextW; prevW = 0; for (w = workers; w; w = nextW) { nextW = w->next; if (w->exitCode != RXKST_PROCESSRUNNING) { if (w->exitCode) { if (code == 0) code = w->exitCode; } if (prevW) prevW->next = w->next; else workers = w->next; osi_Free(w, sizeof(*w)); continue; /* don't bump prevW */ } prevW = w; } #ifdef AFS_PTHREAD_ENV if (workers) pthread_cond_wait(&workerCV, &workerLock); #else if (workers) LWP_WaitProcess(&workers); #endif } #ifdef AFS_PTHREAD_ENV pthread_mutex_unlock(&workerLock); #endif return code; }
/* initialization function that has to be called before threads are spawned */ void sge_err_init(void) { DENTER(ERR_LAYER, "sge_err_init"); pthread_once(&sge_err_once, sge_err_once_init); DEXIT; }
/* Initializes the timetracking module, if not already initialized. */ static void time_init(void) { static pthread_once_t once = PTHREAD_ONCE_INIT; pthread_once(&once, do_init_time); }
static long RunHijackTest(struct clientParms *parms, long host, struct rx_securityClass *sc, long si) { #ifndef rx_GetPacketCksum code = RXKST_BADARGS; afs_com_err(whoami, code, "Older versions of Rx don't export packet tracing routines: can't run this HijackTest"); return code; #else long code; struct rx_connection *conn = 0; struct rx_connection *otherConn = 0; #ifdef AFS_PTHREAD_ENV pthread_t pid; #else PROCESS pid; #endif int nResp; /* otherConn responses seen */ long tmp_rc; #ifdef AFS_PTHREAD_ENV pthread_once(&slowCallOnce, SlowCallInit); #endif rx_justReceived = HandleIncoming; rx_almostSent = HandleOutgoing; incomingOps.op = IO_NOOP; outgoingOps.op = OO_NOOP; #define HIJACK_CONN(conn) \ { if (conn) rx_DestroyConnection (conn); \ (conn) = rx_NewConnection(host, htons(RXKST_SERVICEPORT), \ RXKST_SERVICEID, sc, si); \ if (!(conn)) return RXKST_NEWCONNFAILED; \ outgoingOps.client = 1; \ outgoingOps.epoch = (conn)->epoch; \ outgoingOps.cid = (conn)->cid; } HIJACK_CONN(conn); /* First try switching from no packet cksum to sending packet cksum between * calls, and see if server complains. */ outgoingOps.op = OO_ZEROCKSUM; code = FastCall(conn); if (code) { afs_com_err(whoami, code, "doing FastCall with ZEROCKSUM"); return code; } /* The server thinks we're an old style client. Now start sending cksums. * Server shouldn't care. */ outgoingOps.op = OO_NOOP; code = FastCall(conn); if (code) { afs_com_err(whoami, code, "doing FastCall with non-ZEROCKSUM"); return code; } /* The server now thinks we're a new style client, we can't go back now. */ outgoingOps.op = OO_ZEROCKSUM; code = FastCall(conn); if (code == 0) code = RXKST_NOBADCKSUM; if (code != RXKADSEALEDINCON) { afs_com_err(whoami, code, "doing FastCall with ZEROCKSUM"); return code; } else if (!conn->error) { code = RXKST_NOCONNERROR; afs_com_err(whoami, code, "doing FastCall with ZEROCKSUM"); return code; } else code = 0; HIJACK_CONN(conn); /* Now try modifying packet cksum to see if server complains. */ outgoingOps.op = OO_MUNGCKSUM; code = FastCall(conn); if (code == 0) code = RXKST_NOBADCKSUM; if (code != RXKADSEALEDINCON) { afs_com_err(whoami, code, "doing FastCall with ZEROCKSUM"); return code; } else if (!conn->error) { code = RXKST_NOCONNERROR; afs_com_err(whoami, code, "doing FastCall with ZEROCKSUM"); return code; } else code = 0; /* Now make two connection and direct the first challenge on one connection * to the other connection to see if it generates a response. The * retransmitted challenge should allow the call on the first connection to * complete correctly. Part one is to attack a new connection, then attack * it after it has made a call. Part three, just for comparison, attacks a * otherConn while it is making a slow call (and thus has an active call). * Against this attack we have no defense so we expect a challenge in this * case, which the server will discard. */ #define RedirectChallenge(conn,otherConn) \ (incomingOps.epoch = (conn)->epoch, \ incomingOps.cid = (conn)->cid, \ incomingOps.client = 1, \ incomingOps.newEpoch = (otherConn)->epoch, \ incomingOps.newCid = (otherConn)->cid, \ incomingOps.op = IO_REDIRECTCHALLENGE, \ outgoingOps.epoch = (otherConn)->epoch, \ outgoingOps.cid = (otherConn)->cid, \ outgoingOps.client = 1, \ outgoingOps.op = OO_COUNT, \ outgoingOps.counts[RX_PACKET_TYPE_RESPONSE] = 0) HIJACK_CONN(conn); HIJACK_CONN(otherConn) RedirectChallenge(conn, otherConn); code = FastCall(conn); if (code) return code; assert(incomingOps.op == IO_COUNT); /* redirect code was triggered */ if (outgoingOps.counts[RX_PACKET_TYPE_RESPONSE] > 0) { oracle: code = RXKST_CHALLENGEORACLE; afs_com_err(whoami, code, "misdirecting challenge"); return code; } code = FastCall(otherConn); /* generate some activity here */ if (code) return code; nResp = outgoingOps.counts[RX_PACKET_TYPE_RESPONSE]; assert(nResp >= 1); code = FastCall(conn); if (code) return code; if (outgoingOps.counts[RX_PACKET_TYPE_RESPONSE] > nResp) goto oracle; HIJACK_CONN(conn); RedirectChallenge(conn, otherConn); /* otherConn was authenticated during part one */ code = FastCall(conn); if (code) return code; assert(incomingOps.op == IO_COUNT); /* redirect code was triggered */ if (outgoingOps.counts[RX_PACKET_TYPE_RESPONSE] != 0) goto oracle; HIJACK_CONN(conn); RedirectChallenge(conn, otherConn); /* otherConn is still authenticated */ slowCallCode = RXKST_PROCESSCREATED; #ifdef AFS_PTHREAD_ENV { pthread_attr_t tattr; code = pthread_attr_init(&tattr); if (code) { afs_com_err(whoami, code, "can't pthread_attr_init slow call process"); return code; } code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) { afs_com_err(whoami, code, "can't pthread_attr_setdetachstate slow call process"); return code; } code = pthread_create(&pid, &tattr, SlowCall, (void *)otherConn); } #else code = LWP_CreateProcess(SlowCall, 16000, LWP_NORMAL_PRIORITY, (opaque) otherConn, "Slow Call Process", &pid); #endif if (code) { afs_com_err(whoami, code, "can't create slow call process"); return code; } #ifdef AFS_PTHREAD_ENV pthread_mutex_lock(&slowCallLock); while (slowCallCode == RXKST_PROCESSCREATED) pthread_cond_wait(&slowCallCV, &slowCallLock); #else while (slowCallCode == RXKST_PROCESSCREATED) LWP_WaitProcess(&slowCallCode); /* wait for process start */ #endif if (slowCallCode != RXKST_PROCESSRUNNING) { tmp_rc = slowCallCode; #ifdef AFS_PTHREAD_ENV pthread_mutex_unlock(&slowCallLock); #endif return tmp_rc; /* make sure didn't fail immediately */ } assert(incomingOps.op == IO_REDIRECTCHALLENGE); code = FastCall(conn); if (code) return code; assert(incomingOps.op == IO_COUNT); /* redirect code was triggered */ #ifdef AFS_PTHREAD_ENV while (slowCallCode == RXKST_PROCESSRUNNING) pthread_cond_wait(&slowCallCV, &slowCallLock); pthread_mutex_unlock(&slowCallLock); #else while (slowCallCode == RXKST_PROCESSRUNNING) LWP_WaitProcess(&slowCallCode); /* wait for process finish */ #endif if (outgoingOps.counts[RX_PACKET_TYPE_RESPONSE] != 1) goto oracle; rx_justReceived = 0; rx_almostSent = 0; rx_DestroyConnection(otherConn); rx_DestroyConnection(conn); return code; #endif /* rx_GetPacketCksum */ }
static void epicsThreadInit(void) { static pthread_once_t once_control = PTHREAD_ONCE_INIT; int status = pthread_once(&once_control,once); checkStatusQuit(status,"pthread_once","epicsThreadInit"); }
static void initialize(void) { pthread_once(&gWrapSimInitialized, initOnce); }
lae_stream * lae_stderr() { static pthread_once_t once = PTHREAD_ONCE_INIT; pthread_once( &once, lae_filestream_stderr_init ); return filestream_stderr; }
void initializeWebThread() { pthread_once(&initializeWebThreadKeyOnce, initializeWebThreadOnce); }
int virOnce(virOnceControlPtr once, virOnceFunc init) { return pthread_once(&once->once, init); }
void initializeMainThreadToProcessMainThread() { pthread_once(&initializeMainThreadKeyOnce, initializeMainThreadToProcessMainThreadOnce); }
CfLock AcquireLock(char *operand, char *host, time_t now, Attributes attr, Promise *pp, int ignoreProcesses) { unsigned int pid; int i, err, sum = 0; time_t lastcompleted = 0, elapsedtime; char *promise, cc_operator[CF_BUFSIZE], cc_operand[CF_BUFSIZE]; char cflock[CF_BUFSIZE], cflast[CF_BUFSIZE], cflog[CF_BUFSIZE]; char str_digest[CF_BUFSIZE]; CfLock this; unsigned char digest[EVP_MAX_MD_SIZE + 1]; /* Register a cleanup handler */ pthread_once(&lock_cleanup_once, &RegisterLockCleanup); this.last = (char *) CF_UNDEFINED; this.lock = (char *) CF_UNDEFINED; this.log = (char *) CF_UNDEFINED; if (now == 0) { return this; } this.last = NULL; this.lock = NULL; this.log = NULL; /* Indicate as done if we tried ... as we have passed all class constraints now but we should only do this for level 0 promises. Sub routine bundles cannot be marked as done or it will disallow iteration over bundles */ if (pp->done) { return this; } if (RlistLen(CF_STCK) == 1) { *(pp->donep) = true; /* Must not set pp->done = true for editfiles etc */ } PromiseHash(pp, operand, digest, CF_DEFAULT_DIGEST); HashPrintSafe(CF_DEFAULT_DIGEST, digest, str_digest); /* As a backup to "done" we need something immune to re-use */ if (THIS_AGENT_TYPE == AGENT_TYPE_AGENT) { if (IsItemIn(DONELIST, str_digest)) { CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> This promise has already been verified"); return this; } PrependItem(&DONELIST, str_digest, NULL); } /* Finally if we're supposed to ignore locks ... do the remaining stuff */ if (IGNORELOCK) { this.lock = xstrdup("dummy"); return this; } promise = BodyName(pp); snprintf(cc_operator, CF_MAXVARSIZE - 1, "%s-%s", promise, host); strncpy(cc_operand, operand, CF_BUFSIZE - 1); CanonifyNameInPlace(cc_operand); RemoveDates(cc_operand); free(promise); CfDebug("AcquireLock(%s,%s), ExpireAfter=%d, IfElapsed=%d\n", cc_operator, cc_operand, attr.transaction.expireafter, attr.transaction.ifelapsed); for (i = 0; cc_operator[i] != '\0'; i++) { sum = (CF_MACROALPHABET * sum + cc_operator[i]) % CF_HASHTABLESIZE; } for (i = 0; cc_operand[i] != '\0'; i++) { sum = (CF_MACROALPHABET * sum + cc_operand[i]) % CF_HASHTABLESIZE; } snprintf(cflog, CF_BUFSIZE, "%s/cf3.%.40s.runlog", CFWORKDIR, host); snprintf(cflock, CF_BUFSIZE, "lock.%.100s.%s.%.100s_%d_%s", PromiseGetBundle(pp)->name, cc_operator, cc_operand, sum, str_digest); snprintf(cflast, CF_BUFSIZE, "last.%.100s.%s.%.100s_%d_%s", PromiseGetBundle(pp)->name, cc_operator, cc_operand, sum, str_digest); CfDebug("LOCK(%s)[%s]\n", PromiseGetBundle(pp)->name, cflock); // Now see if we can get exclusivity to edit the locks CFINITSTARTTIME = time(NULL); WaitForCriticalSection(); /* Look for non-existent (old) processes */ lastcompleted = FindLock(cflast); elapsedtime = (time_t) (now - lastcompleted) / 60; if (elapsedtime < 0) { CfOut(OUTPUT_LEVEL_VERBOSE, "", " XX Another cf-agent seems to have done this since I started (elapsed=%jd)\n", (intmax_t) elapsedtime); ReleaseCriticalSection(); return this; } if (elapsedtime < attr.transaction.ifelapsed) { CfOut(OUTPUT_LEVEL_VERBOSE, "", " XX Nothing promised here [%.40s] (%jd/%u minutes elapsed)\n", cflast, (intmax_t) elapsedtime, attr.transaction.ifelapsed); ReleaseCriticalSection(); return this; } /* Look for existing (current) processes */ if (!ignoreProcesses) { lastcompleted = FindLock(cflock); elapsedtime = (time_t) (now - lastcompleted) / 60; if (lastcompleted != 0) { if (elapsedtime >= attr.transaction.expireafter) { CfOut(OUTPUT_LEVEL_INFORM, "", "Lock %s expired (after %jd/%u minutes)\n", cflock, (intmax_t) elapsedtime, attr.transaction.expireafter); pid = FindLockPid(cflock); if (pid == -1) { CfOut(OUTPUT_LEVEL_ERROR, "", "Illegal pid in corrupt lock %s - ignoring lock\n", cflock); } #ifdef __MINGW32__ // killing processes with e.g. task manager does not allow for termination handling else if (!NovaWin_IsProcessRunning(pid)) { CfOut(OUTPUT_LEVEL_VERBOSE, "", "Process with pid %d is not running - ignoring lock (Windows does not support graceful processes termination)\n", pid); LogLockCompletion(cflog, pid, "Lock expired, process not running", cc_operator, cc_operand); unlink(cflock); } #endif /* __MINGW32__ */ else { CfOut(OUTPUT_LEVEL_VERBOSE, "", "Trying to kill expired process, pid %d\n", pid); err = GracefulTerminate(pid); if (err || (errno == ESRCH) || (errno == ETIMEDOUT)) { LogLockCompletion(cflog, pid, "Lock expired, process killed", cc_operator, cc_operand); unlink(cflock); } else { ReleaseCriticalSection(); FatalError("Unable to kill expired cfagent process %d from lock %s, exiting this time..\n", pid, cflock); } } } else { ReleaseCriticalSection(); CfOut(OUTPUT_LEVEL_VERBOSE, "", "Couldn't obtain lock for %s (already running!)\n", cflock); return this; } } WriteLock(cflock); } ReleaseCriticalSection(); this.lock = xstrdup(cflock); this.last = xstrdup(cflast); this.log = xstrdup(cflog); /* Keep this as a global for signal handling */ strcpy(CFLOCK, cflock); strcpy(CFLAST, cflast); strcpy(CFLOG, cflog); return this; }
int chpl_topo_getNumCPUsLogical(chpl_bool accessible_only) { CHK_ERR(pthread_once(&numCPUs_ctrl, getNumCPUs) == 0); return (accessible_only) ? numCPUsLogAcc : numCPUsLogAll; }
extern errno_t vnode_create(int flavor, size_t size, void *data, vnode_t *vnPtr) { int err; int junk; vnode_t vn; vnode_t newVN; vnode_t vnToRecycle; CFIndex vnCount; CFIndex vnIndex; static pthread_once_t sVNodesControl = PTHREAD_ONCE_INIT; assert(flavor == VNCREATE_FLAVOR); assert(size == VCREATESIZE); assert(data != NULL); assert(vnPtr != NULL); // Initialise gVNodes junk = pthread_once(&sVNodesControl, InitVNodes); assert(junk == 0); newVN = NULL; vn = NULL; vnToRecycle = NULL; do { err = EAGAIN; junk = pthread_mutex_lock(&gVNodesLock); assert(junk == 0); vnCount = CFArrayGetCount(gVNodes); if (vnCount < gVNodesMax) { // We can just add a vnode. if (newVN == NULL) { junk = pthread_mutex_unlock(&gVNodesLock); assert(junk == 0); newVN = (vnode_t) malloc(sizeof(*vn)); assert(newVN != NULL); junk = pthread_mutex_init(&newVN->mtx, NULL); assert(junk == 0); newVN->getPutRefCount = 1; newVN->vid = 0; newVN->fsnode = ((struct vnode_fsparam *) data)->vnfs_fsnode; junk = pthread_mutex_lock(&gVNodesLock); assert(junk == 0); } else { CFArrayAppendValue(gVNodes, newVN); vn = newVN; newVN = NULL; err = 0; } } else { // We must recycle a vnode. for (vnIndex = 0; vnIndex < vnCount; vnIndex++) { vnode_t thisVN; thisVN = (vnode_t) CFArrayGetValueAtIndex(gVNodes, vnIndex); if (thisVN->getPutRefCount == 0) { vnToRecycle = thisVN; err = 0; // Move the vnode we're recycling (well, the one that // we're /planning/ to recycle) to the end of the list, // so that it doesn't get immediately recycled again. CFArrayRemoveValueAtIndex(gVNodes, vnIndex); CFArrayAppendValue(gVNodes, vnToRecycle); break; } } } junk = pthread_mutex_unlock(&gVNodesLock); assert(junk == 0); if ( (err == 0) && (vnToRecycle != NULL) ) { assert(vn == NULL); junk = pthread_mutex_lock(&vnToRecycle->mtx); assert(junk == 0); if (vnToRecycle->getPutRefCount == 0) { // Stop anyone else messing with it vnToRecycle->getPutRefCount = 1; // Detach it from the file system. This is super bogus because // we're doing this with the vnode lock held. If the client code // called back into us to do anything interesting, they'd deadlock. // However, that currently doesn't happen and, besides, dropping // the lock is /hard/ (just look at the VFS implementation :-). gReclaimCallback(vnToRecycle); // invalidate any cached references vnToRecycle->vid += 1; vnToRecycle->fsnode = ((struct vnode_fsparam *) data)->vnfs_fsnode; junk = pthread_mutex_unlock(&vnToRecycle->mtx); assert(junk == 0); vn = vnToRecycle; err = 0; } else { junk = pthread_mutex_unlock(&vnToRecycle->mtx); assert(junk == 0); // Someone started using the vnode between our test (inside the // for loop, above) and us locking the vnode. We just start again // from the beginning. vnToRecycle = NULL; err = EAGAIN; } } } while (err == EAGAIN); assert(err == 0); // Didn't use our new vnode, so junk it. if (newVN != NULL) { junk = pthread_mutex_destroy(&newVN->mtx); assert(junk == 0); free(newVN); } *vnPtr = vn; return 0; }
void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) { if (pthread_once(once, init) != 0) { abort(); } }
static pthread_cond_t * ChannelToCond(void *chan) { int err; int junk; pthread_cond_t * cond; pthread_cond_t * newCond; static pthread_once_t sChannelToCondControl = PTHREAD_ONCE_INIT; newCond = NULL; // Lazy init of gChannelToCond. junk = pthread_once(&sChannelToCondControl, InitChannelToCond); assert(junk == 0); // Look up the channel to find or create the associated conditional variable. junk = pthread_mutex_lock(&gChannelToCondLock); assert(junk == 0); do { err = 0; cond = (pthread_cond_t *) CFDictionaryGetValue(gChannelToCond, chan); if (cond == NULL) { if (newCond == NULL) { junk = pthread_mutex_unlock(&gChannelToCondLock); assert(junk == 0); newCond = (pthread_cond_t *) malloc(sizeof(*newCond)); assert(newCond != NULL); junk = pthread_cond_init(newCond, NULL); assert(junk == 0); err = EAGAIN; junk = pthread_mutex_lock(&gChannelToCondLock); assert(junk == 0); } else { CFDictionaryAddValue(gChannelToCond, chan, newCond); cond = newCond; newCond = NULL; } } } while (err == EAGAIN); junk = pthread_mutex_unlock(&gChannelToCondLock); assert(junk == 0); // If we created newCond but didn't use it, free it now. if (newCond != NULL) { junk = pthread_cond_destroy(newCond); assert(junk == 0); free(newCond); } return cond; }
void uv_once(uv_once_t* guard, void (*callback)(void)) { if (pthread_once(guard, callback)) abort(); }
void Pthread_once(pthread_once_t *once_control, void (*init_function)()) { pthread_once(once_control, init_function); }
static struct _Unwind_FunctionContext* __Unwind_SjLj_GetTopOfFunctionStack() { pthread_once(&sOnceFlag, __Unwind_SjLj_MakeTopOfFunctionStackKey); return (struct _Unwind_FunctionContext*)pthread_getspecific(sPerThreadTopOfFunctionStack); }
/****** uti/bootstrap/bootstrap_mt_init() ********************************** * NAME * bootstrap_mt_init() -- Initialize bootstrap code for multi threading use. * * SYNOPSIS * void bootstrap_mt_init(void) * * FUNCTION * Set up bootstrap code. This function must be called at least once before * any of the bootstrap oriented functions can be used. This function is * idempotent, i.e. it is safe to call it multiple times. * * Thread local storage for the bootstrap state information is reserved. * * INPUTS * void - NONE * * RESULT * void - NONE * * NOTES * MT-NOTE: bootstrap_mt_init() is MT safe * *******************************************************************************/ void bootstrap_mt_init(void) { pthread_once(&bootstrap_once, bootstrap_thread_local_once_init); }
/* * Initialize the UUID module. Aborts the program with an error message if * initialization fails (which should never happen on a properly configured * machine.) * * Currently initialization is only needed by uuid_generate(). uuid_generate() * will automatically call uuid_init() itself, so it's only necessary to call * this function explicitly if you want to abort the program earlier than the * first UUID generation in case of failure. */ void uuid_init(void) { static pthread_once_t once = PTHREAD_ONCE_INIT; pthread_once(&once, do_init); }
static __inline void emutls_init_once(void) { static pthread_once_t once = PTHREAD_ONCE_INIT; pthread_once(&once, emutls_init); }
QThreadInstance *QThreadInstance::current() { pthread_once( &storage_key_once, create_storage_key ); QThreadInstance *ret = (QThreadInstance *) pthread_getspecific( storage_key ); return ret; }
_X_HIDDEN void __glXSetCurrentContext(struct glx_context * c) { pthread_once(&once_control, init_thread_data); pthread_setspecific(ContextTSD, c); }