Пример #1
0
/*++
 * @name CsrNotifyWait
 * @implemented NT4
 *
 * The CsrNotifyWait notifies a CSR Wait Block.
 *
 * @param WaitList
 *        Pointer to the list entry for this wait.
 *
 * @param WaitType
 *        Type of the wait to perform, either WaitAny or WaitAll.
 *
 * @param WaitArgument[1-2]
 *        User-defined argument to pass on to the wait function.
 *
 * @return TRUE in case of success, FALSE othwerwise.
 *
 * @remarks None.
 *
 *--*/
BOOLEAN
NTAPI
CsrNotifyWait(IN PLIST_ENTRY WaitList,
              IN ULONG WaitType,
              IN PVOID WaitArgument1,
              IN PVOID WaitArgument2)
{
    PLIST_ENTRY NextEntry;
    PCSR_WAIT_BLOCK WaitBlock;
    BOOLEAN NotifySuccess = FALSE;

    /* Acquire the Wait Lock */
    CsrAcquireWaitLock();

    /* Set the List pointers */
    NextEntry = WaitList->Flink;

    /* Start looping */
    while (NextEntry != WaitList)
    {
        /* Get the Wait block */
        WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);

        /* Go to the next entry */
        NextEntry = NextEntry->Flink;

        /* Check if there is a Wait Callback */
        if (WaitBlock->WaitFunction)
        {
            /* Notify the Waiter */
            NotifySuccess |= CsrNotifyWaitBlock(WaitBlock,
                                                WaitList,
                                                WaitArgument1,
                                                WaitArgument2,
                                                0,
                                                FALSE);
            
            /* We've already done a wait, so leave unless this is a Wait All */
            if (WaitType != WaitAll) break;
        }
    }

    /* Release the wait lock and return */
    CsrReleaseWaitLock();
    return NotifySuccess;
}
Пример #2
0
/*++
 * @name CsrDestroyProcess
 * @implemented NT4
 *
 * The CsrDestroyProcess routine destroys the CSR Process corresponding to
 * a given Client ID.
 *
 * @param Cid
 *        Pointer to the Client ID Structure corresponding to the CSR
 *        Process which is about to be destroyed.
 *
 * @param ExitStatus
 *        Unused.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING
 *         if the CSR Process is already terminating.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrDestroyProcess(IN PCLIENT_ID Cid,
                  IN NTSTATUS ExitStatus)
{
    PCSR_THREAD CsrThread;
    PCSR_PROCESS CsrProcess;
    CLIENT_ID ClientId = *Cid;
    PLIST_ENTRY NextEntry;

    /* Acquire lock */
    CsrAcquireProcessLock();

    /* Find the thread */
    CsrThread = CsrLocateThreadByClientId(&CsrProcess, &ClientId);

    /* Make sure we got one back, and that it's not already gone */
    if (!(CsrThread) || (CsrProcess->Flags & CsrProcessTerminating))
    {
        /* Release the lock and return failure */
        CsrReleaseProcessLock();
        return STATUS_THREAD_IS_TERMINATING;
    }

    /* Set the terminated flag */
    CsrProcess->Flags |= CsrProcessTerminating;

    /* Get the List Pointers */
    NextEntry = CsrProcess->ThreadList.Flink;
    while (NextEntry != &CsrProcess->ThreadList)
    {
        /* Get the current thread entry */
        CsrThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);

        /* Move to the next entry */
        NextEntry = NextEntry->Flink;

        /* Make sure the thread isn't already dead */
        if (CsrThread->Flags & CsrThreadTerminated)
        {
            /* Go the the next thread */
            continue;
        }

        /* Set the Terminated flag */
        CsrThread->Flags |= CsrThreadTerminated;

        /* Acquire the Wait Lock */
        CsrAcquireWaitLock();

        /* Do we have an active wait block? */
        if (CsrThread->WaitBlock)
        {
            /* Notify waiters of termination */
            CsrNotifyWaitBlock(CsrThread->WaitBlock,
                               NULL,
                               NULL,
                               NULL,
                               CsrProcessTerminating,
                               TRUE);
        }

        /* Release the Wait Lock */
        CsrReleaseWaitLock();

        /* Dereference the thread */
        CsrLockedDereferenceThread(CsrThread);
    }

    /* Release the Process Lock and return success */
    CsrReleaseProcessLock();
    return STATUS_SUCCESS;
}