Пример #1
0
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);
    }
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}