VOID RdrTree2Release( RDR_TREE2 *pTree ) { BOOLEAN bInLock = FALSE; LW_TASK_EVENT_MASK dummy = 0; LONG64 llDummy = 0; LWIO_LOCK_MUTEX(bInLock, &pTree->pSession->mutex); assert(pTree->refCount > 0); if (--pTree->refCount == 0) { if (pTree->state != RDR_TREE_STATE_READY || !RdrSocketIsValid(pTree->pSession->pSocket)) { RdrTree2Unlink(pTree); LWIO_UNLOCK_MUTEX(bInLock, &pTree->pSession->mutex); RdrTree2Free(pTree); } else { LWIO_LOG_VERBOSE("Tree %p is eligible for reaping", pTree); LWIO_UNLOCK_MUTEX(bInLock, &pTree->pSession->mutex); if (LwRtlCreateTask( gRdrRuntime.pThreadPool, &pTree->pTimeout, gRdrRuntime.pTreeTimerGroup, RdrTree2Timeout, pTree) == STATUS_SUCCESS) { LwRtlWakeTask(pTree->pTimeout); } else { LWIO_LOG_ERROR("Could not create timer for tree %p; disconnecting immediately"); RdrTree2Timeout(NULL, pTree, LW_TASK_EVENT_TIME, &dummy, &llDummy); } } } else { LWIO_UNLOCK_MUTEX(bInLock, &pTree->pSession->mutex); } }
static DWORD LwSmMain( VOID ) { DWORD dwError = 0; PLW_TASK pTask = NULL; dwError = LwNtStatusToWin32Error(LwRtlCreateTask( gpPool, &pTask, NULL, MainTask, NULL)); BAIL_ON_ERROR(dwError); LwRtlWakeTask(pTask); dwError = LwNtStatusToWin32Error(LwRtlMain()); BAIL_ON_ERROR(dwError); cleanup: if (pTask) { LwRtlCancelTask(pTask); LwRtlWaitTask(pTask); LwRtlReleaseTask(&pTask); } return dwError; error: goto cleanup; }
NTSTATUS LwRtlCreateTask( PLW_THREAD_POOL pPool, PLW_TASK* ppTask, PLW_TASK_GROUP pGroup, LW_TASK_FUNCTION pfnFunc, PVOID pContext ) { NTSTATUS status = STATUS_SUCCESS; PEPOLL_TASK pTask = NULL; PEPOLL_THREAD pThread = NULL; ULONG ulMinLoad = 0xFFFFFFFF; ULONG ulIndex = 0; if (pPool->pDelegate) { return LwRtlCreateTask(pPool->pDelegate, ppTask, pGroup, pfnFunc, pContext); } status = LW_RTL_ALLOCATE_AUTO(&pTask); GOTO_ERROR_ON_STATUS(status); RingInit(&pTask->GroupRing); RingInit(&pTask->QueueRing); RingInit(&pTask->SignalRing); pTask->pGroup = pGroup; pTask->ulRefCount = 2; pTask->pfnFunc = pfnFunc; pTask->pFuncContext = pContext; pTask->Fd = -1; pTask->EventArgs = LW_TASK_EVENT_INIT; pTask->EventWait = LW_TASK_EVENT_EXPLICIT; pTask->llDeadline = 0; LOCK_POOL(pPool); for (ulIndex = 0; ulIndex < pPool->ulEventThreadCount; ulIndex++) { if (pPool->pEventThreads[ulIndex].ulLoad < ulMinLoad) { pThread = &pPool->pEventThreads[ulIndex]; ulMinLoad = pThread->ulLoad; } } pTask->pThread = pThread; if (pGroup) { LOCK_GROUP(pGroup); if (pGroup->bCancelled) { UNLOCK_GROUP(pGroup); UNLOCK_POOL(pPool); status = STATUS_CANCELLED; GOTO_ERROR_ON_STATUS(status); } RingInsertBefore(&pGroup->Tasks, &pTask->GroupRing); UNLOCK_GROUP(pGroup); } pThread->ulLoad++; UNLOCK_POOL(pPool); *ppTask = pTask; cleanup: return status; error: if (pTask) { TaskDelete(pTask); } *ppTask = NULL; goto cleanup; }
NTSTATUS LwRtlCreateTask( PLW_THREAD_POOL pPool, PLW_TASK* ppTask, PLW_TASK_GROUP pGroup, LW_TASK_FUNCTION pfnFunc, PVOID pContext ) { NTSTATUS status = STATUS_SUCCESS; PSELECT_TASK pTask = NULL; if (pPool->pDelegate) { return LwRtlCreateTask(pPool->pDelegate, ppTask, pGroup, pfnFunc, pContext); } GOTO_ERROR_ON_STATUS(status = LW_RTL_ALLOCATE_AUTO(&pTask)); RingInit(&pTask->GroupRing); RingInit(&pTask->EventRing); pTask->pPool = pPool; pTask->pGroup = pGroup; pTask->ulRefCount = 2; pTask->pfnFunc = pfnFunc; pTask->pFuncContext = pContext; pTask->Fd = -1; pTask->TriggerSet = LW_TASK_EVENT_INIT; pTask->TriggerWait = LW_TASK_EVENT_EXPLICIT; pTask->llDeadline = 0; LOCK_POOL(pPool); if (pGroup) { LOCK_GROUP(pGroup); if (pGroup->bCancelled) { UNLOCK_GROUP(pGroup); UNLOCK_POOL(pPool); status = STATUS_CANCELLED; GOTO_ERROR_ON_STATUS(status); } RingInsertBefore(&pGroup->Tasks, &pTask->GroupRing); } pTask->pThread = &pPool->pEventThreads[pPool->ulNextEventThread]; pPool->ulNextEventThread = (pPool->ulNextEventThread + 1) % pPool->ulEventThreadCount; UNLOCK_POOL(pPool); LOCK_THREAD(pTask->pThread); RingInsertBefore(&pTask->pThread->Tasks, &pTask->EventRing); /* It's not necessary to signal the thread about the new task here since it won't be run anyway */ UNLOCK_THREAD(pTask->pThread); if (pGroup) { UNLOCK_GROUP(pGroup); } *ppTask = pTask; error: return status; }
static NTSTATUS CreateSocketPair( PLW_TASK_GROUP pGroup, PSOCKET* ppSocket1, PSOCKET* ppSocket2 ) { NTSTATUS status = STATUS_SUCCESS; PSOCKET pSocket1 = NULL; PSOCKET pSocket2 = NULL; int socketFds[2] = {-1, -1}; status = LW_RTL_ALLOCATE_AUTO(&pSocket1); GOTO_ERROR_ON_STATUS(status); status = LW_RTL_ALLOCATE_AUTO(&pSocket2); GOTO_ERROR_ON_STATUS(status); status = LW_RTL_ALLOCATE_ARRAY_AUTO(&pSocket1->pBuffer, gpSettings->ulBufferSize); GOTO_ERROR_ON_STATUS(status); status = LW_RTL_ALLOCATE_ARRAY_AUTO(&pSocket2->pBuffer, gpSettings->ulBufferSize); GOTO_ERROR_ON_STATUS(status); if (socketpair(AF_UNIX, SOCK_STREAM, 0, socketFds) < 0) { status = LwErrnoToNtStatus(errno); GOTO_ERROR_ON_STATUS(status); } pSocket1->Fd = socketFds[0]; pSocket2->Fd = socketFds[1]; pSocket1->State = STATE_SEND; pSocket2->State = STATE_RECV; status = LwRtlCreateTask( gpPool, &pSocket1->pTask, pGroup, Transceiver, pSocket1); GOTO_ERROR_ON_STATUS(status); status = LwRtlCreateTask( gpPool, &pSocket2->pTask, pGroup, Transceiver, pSocket2); GOTO_ERROR_ON_STATUS(status); *ppSocket1 = pSocket1; *ppSocket2 = pSocket2; cleanup: return status; error: goto cleanup; }
static DWORD LwSmCmdTapLog( int argc, char** pArgv ) { DWORD error = ERROR_SUCCESS; PLW_THREAD_POOL pPool = NULL; PLW_TASK pTask = NULL; BOOLEAN bResetLogger = FALSE; BOOLEAN bRmPipe = FALSE; LW_SM_LOGGER_TYPE oldLogger = 0; PSTR pOldTarget = NULL; LW_SM_LOG_LEVEL oldLevel = 0; LW_SM_LOG_LEVEL newLevel = 0; PSTR pFacility = NULL; LW_SERVICE_HANDLE hHandle = NULL; PWSTR pServiceName = NULL; PSTR pFifo = NULL; int FifoFd = -1; if (argc < 4) { error = LW_ERROR_INVALID_PARAMETER; BAIL_ON_ERROR(error); } if (strcmp(pArgv[1], "-")) { error = LwMbsToWc16s(pArgv[1], &pServiceName); BAIL_ON_ERROR(error); error = LwSmAcquireServiceHandle(pServiceName, &hHandle); BAIL_ON_ERROR(error); } if (strcmp(pArgv[2], "-")) { pFacility = pArgv[2]; } error = LwSmLogLevelNameToLogLevel(pArgv[3], &newLevel); BAIL_ON_ERROR(error); error = LwSmGetServiceLogState(hHandle, pFacility, &oldLogger, &pOldTarget, &oldLevel); BAIL_ON_ERROR(error); error = LwAllocateStringPrintf(&pFifo, "/tmp/.lwsm-log-tap-%lu", (unsigned long) getpid()); BAIL_ON_ERROR(error); LwRtlBlockSignals(); if (mknod(pFifo, S_IRUSR | S_IWUSR | S_IFIFO, 0) < 0) { error = LwErrnoToWin32Error(errno); BAIL_ON_ERROR(error); } bRmPipe = TRUE; if ((FifoFd = open(pFifo, O_RDONLY | O_NONBLOCK)) < 0) { error = LwErrnoToWin32Error(errno); BAIL_ON_ERROR(error); } if (fcntl(FifoFd, F_SETFL, O_NONBLOCK) < 0) { error = LwErrnoToWin32Error(errno); BAIL_ON_ERROR(error); } error = LwSmSetServiceLogTarget(hHandle, pFacility, LW_SM_LOGGER_FILE, pFifo); BAIL_ON_ERROR(error); bResetLogger = TRUE; error = LwSmSetServiceLogLevel(hHandle, pFacility, newLevel); BAIL_ON_ERROR(error); error = LwNtStatusToWin32Error(LwRtlCreateThreadPool(&pPool, NULL)); BAIL_ON_ERROR(error); error = LwNtStatusToWin32Error(LwRtlCreateTask(pPool, &pTask, NULL, LogTapper, &FifoFd)); BAIL_ON_ERROR(error); LwRtlWakeTask(pTask); error = LwNtStatusToWin32Error(LwRtlMain()); BAIL_ON_ERROR(error); error: if (pTask) { LwRtlCancelTask(pTask); LwRtlWaitTask(pTask); LwRtlReleaseTask(&pTask); } LwRtlFreeThreadPool(&pPool); if (bResetLogger) { error = LwSmSetServiceLogLevel(hHandle, pFacility, oldLevel); BAIL_ON_ERROR(error); error = LwSmSetServiceLogTarget(hHandle, pFacility, oldLogger, pOldTarget); BAIL_ON_ERROR(error); } if (pOldTarget) { LwSmFreeLogTarget(pOldTarget); } if (FifoFd >= 0) { close(FifoFd); } if (bRmPipe) { unlink(pFifo); } LW_SAFE_FREE_MEMORY(pFifo); return error; }