/** * Creates and starts n worker thread */ WorkQueue * WKQ_CreatePool(int n) { size_t size = sizeof(WorkQueue) + sizeof(ThrID)*(MAX(n,1)-1); WorkQueue * q = MEM_Alloc(size); if (q) { ASSERT(WKQ.initcount > 0); if (WKQ.initcount == 0) WKQ_InitModule(); memset(q, 0, size); q->nthreads = n; if (MUTEX_Init(&q->mutex)) { if (EVENT_Init(&q->event)) { if (EVENT_Init(&q->stopEvent)) { if (EVENT_Reset(&q->stopEvent)) { int i; q->flags = WKQ_ACTIVE; QUEUE_Init(&q->items); QUEUE_Init(&q->submit); for (i=0; i<n; i++) { if (!THREAD_Create(q->threads+i, WKQ_Thread, q)) { WKQ_Delete(q); return NULL; } } return q; } EVENT_Destroy(&q->stopEvent); } EVENT_Destroy(&q->event); } MUTEX_Destroy(&q->mutex); } MEM_Free(q); } return NULL; }
LOCAL_FUNC TT_Error TTFile_Done( PEngine_Instance engine ) { MUTEX_Destroy( files.lock ); return TT_Err_Ok; }
/** * Deallocates the system resources used by the lock. */ void RWLOCK_Destroy(RWLock * lock) { QEntry * e; ASSERT(!lock->locks); ASSERT(!lock->entriesInUse); ASSERT(!lock->entriesActive); ASSERT(!lock->shareWaiters.size); ASSERT(!lock->exclusiveWaiters.size); MUTEX_Destroy(&lock->mutex); EVENT_Destroy(&lock->shareEvent); EVENT_Destroy(&lock->exclusiveEvent); /* free dynamically allocated entries */ if (lock->moreEntries) { MEM_Free(lock->moreEntries); lock->moreEntries = NULL; } /* free waiter cache */ while ((e = QUEUE_RemoveHead(&lock->waiterCache)) != NULL) { RWLockWaiter * w = QCAST(e,RWLockWaiter,entry); MEM_Free(w); } /* free dynamically allocated events */ while (lock->eventsInCache > 0) { lock->eventsInCache--; ASSERT(lock->eventCache[lock->eventsInCache]); EVENT_Delete(lock->eventCache[lock->eventsInCache]); lock->eventCache[lock->eventsInCache] = NULL; } lock->numEntries = 0; lock->locks = -1; /* to cause ASSERT if destroyed twice */ }
LOCAL_FUNC TT_Error TTFile_Done( PEngine_Instance engine ) { FREE( files.frame_cache ); MUTEX_Destroy( files.lock ); return TT_Err_Ok; }
/** * Creates MidpSession for the specified XRPC client id. Invoked on the XRPC * thread under synchronization. */ STATIC MidpSession* GWENG_MidpCreateSession(EcmtGateway* gw, int xrpcSid) { MidpSession* ses = MEM_New(MidpSession); if (ses) { LUID luid; /* Just in case if AllocateLocallyUniqueId fails... */ luid.LowPart = (DWORD)ses; AllocateLocallyUniqueId(&luid); memset(ses, 0, sizeof(*ses)); ses->key.xrpcSid = xrpcSid; ses->key.xrpcSession = XRPC_GetCurrentSession(gw->xrpc); ses->sid = luid.LowPart; ASSERT(!HASH_Contains(&gw->ecmtSessionMap,(HashKey)ses->sid)); ASSERT(!HASH_Contains(&gw->midpSessionMap,&ses->key)); if (HASH_Init(&ses->connMap, 1, NULL, NULL, hashFreeValueProc)) { /* Create context for the control connection (number zero) */ MidpConnection* conn = MEM_New(MidpConnection); if (conn) { memset(conn, 0, sizeof(*conn)); if (HASH_Put(&ses->connMap, (HashKey)0, conn)) { if (HASH_Put(&gw->ecmtSessionMap,(HashKey)ses->sid,ses)) { if (HASH_Put(&gw->midpSessionMap, &ses->key, ses)) { if (MUTEX_Init(&ses->xrpcMutex)) { ses->xrpcWorkThread = WKQ_Create(); if (ses->xrpcWorkThread) { ses->xrpcWorkItem = WKI_Create( ses->xrpcWorkThread, GWENG_AsyncXRpc, ses); if (ses->xrpcWorkItem) { QUEUE_Init(&ses->xrpcQueue); TRACE3("GW: new session %08x for " "%08x.%08x\n", ses->sid, ses->key.xrpcSession, ses->key.xrpcSid); return ses; } WKQ_Delete(ses->xrpcWorkThread); } MUTEX_Destroy(&ses->xrpcMutex); } HASH_Remove(&gw->midpSessionMap, &ses->key); } HASH_Remove(&gw->ecmtSessionMap, (HashKey)ses->sid); } } else { MEM_Free(conn); } } HASH_Destroy(&ses->connMap); } MEM_Free(ses); } return NULL; }
/** * Deallocates the work queue */ STATIC void WKQ_Free(WorkQueue * q) { ASSERT(QUEUE_IsEmpty(&q->submit)); ASSERT(QUEUE_IsEmpty(&q->items)); ASSERT(q->flags & WKQ_DEAD); EVENT_Destroy(&q->stopEvent); EVENT_Destroy(&q->event); MUTEX_Destroy(&q->mutex); MEM_Free(q); }
/** * Deallocates the MIDP session context. */ STATIC void GWENG_MidpFree(EcmtGateway* gw, MidpSession* midp) { if (midp) { QEntry* e; VERIFY(HASH_Remove(&gw->midpSessionMap, &midp->key)); HASH_Remove(&gw->ecmtSessionMap, (HashKey)midp->sid); HASH_Destroy(&midp->connMap); WKI_Cancel(midp->xrpcWorkItem); WKI_Detach(midp->xrpcWorkItem); WKQ_Delete(midp->xrpcWorkThread); MUTEX_Destroy(&midp->xrpcMutex); while ((e = QUEUE_RemoveHead(&midp->xrpcQueue)) != NULL) { AsyncXRpcEntry* a = QCAST(e,AsyncXRpcEntry,entry); XRPC_FreeContainer(a->params); MEM_Free(a); } MEM_Free(midp); } }
void WKQ_Shutdown() { if ((--WKQ.initcount) == 0) { while (WKQ.waitpool) { Waiter * next = WKQ.waitpool->next; EVENT_Destroy(&WKQ.waitpool->event); MEM_Free(WKQ.waitpool); WKQ.waitpool = next; WKQ.nwait--; } ASSERT(WKQ.nwait == 0); while (!QUEUE_IsEmpty(&WKQ.itempool)) { QEntry * e = QUEUE_RemoveHead(&WKQ.itempool); WorkItem * w = QCAST(e,WorkItem,itemsQ); MEM_Free(w); } MUTEX_Destroy(&WKQ.mutex); THREAD_Shutdown(); } }
/** * Initialize the lock. */ Bool RWLOCK_Init(RWLock * lock) { LOCK_InitCheck(); memset(lock, 0, sizeof(*lock)); if (MUTEX_Init(&lock->mutex)) { if (EVENT_Init(&lock->shareEvent)) { if (EVENT_Init(&lock->exclusiveEvent)) { QUEUE_Init(&lock->shareWaiters); QUEUE_Init(&lock->exclusiveWaiters); QUEUE_Init(&lock->waiterCache); lock->numEntries = COUNT(lock->staticEntries); lock->lock.type = &LockType_RWLock; return True; } EVENT_Destroy(&lock->shareEvent); } MUTEX_Destroy(&lock->mutex); } return False; }
/** * Initialize random number generator context. */ STATIC Bool RANDOM_Init(Random * r, const RNG * algorithm) { const RNG * rng = (algorithm ? algorithm : (&RNG_Lehmer)); ASSERT(rng->rng_next); ASSERT(rng->rng_seed); if (MUTEX_Init(&r->mutex)) { void * ctx = NULL; if (!rng->rng_init || (ctx = (*(rng->rng_init))(r)) != NULL) { #ifndef __KERNEL__ r->nextGaussian = 0; r->haveNextGaussian = False; #endif /* __KERNEL__ */ r->rng = (*rng); r->ctx = ctx; r->syn = True; /* synchronize by default */ RANDOM_SetSeed(r, RANDOM_GenSeed()); return True; } MUTEX_Destroy(&r->mutex); } return False; }
/** * Destroys the critical section */ void CS_Destroy(CritSect * cs) { ASSERT(!cs->count); MUTEX_Destroy(&cs->mutex); }
/** * Deallocate resources used by the random generator context */ STATIC void RANDOM_Destroy(Random * r) { if (r->rng.rng_free) (*(r->rng.rng_free))(r->ctx); MUTEX_Destroy(&r->mutex); }