/** * 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; }
/** * 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 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); } }