Beispiel #1
0
/*++
 * @name CsrCreateWait
 * @implemented NT4
 *
 * The CsrCreateWait routine creates a CSR Wait.
 *
 * @param WaitList
 *        Pointer to a list entry of the waits to associate.
 *
 * @param WaitFunction
 *        Pointer to the function that will handle this wait.
 *
 * @param CsrWaitThread
 *        Pointer to the CSR Thread that will perform the wait.
 *
 * @param WaitApiMessage
 *        Pointer to the CSR API Message associated to this wait.
 *
 * @param WaitContext
 *        Pointer to a user-defined parameter associated to this wait.
 *
 * @param UserWaitList
 *        Pointer to a list entry of the user-defined waits to associate.
 *
 * @return TRUE in case of success, FALSE otherwise.
 *
 * @remarks None.
 *
 *--*/
BOOLEAN
NTAPI
CsrCreateWait(IN PLIST_ENTRY WaitList,
              IN CSR_WAIT_FUNCTION WaitFunction,
              IN PCSR_THREAD CsrWaitThread,
              IN OUT PCSR_API_MESSAGE WaitApiMessage,
              IN PVOID WaitContext,
              IN PLIST_ENTRY UserWaitList OPTIONAL)
{
    PCSR_WAIT_BLOCK WaitBlock;

    /* Initialize the wait */
    if (!CsrInitializeWait(WaitFunction,
                           CsrWaitThread,
                           WaitApiMessage,
                           WaitContext,
                           &WaitBlock))
    {
        return FALSE;
    }

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

    /* Make sure the thread wasn't destroyed */
    if (CsrWaitThread->Flags & CsrThreadTerminated)
    {
        /* Fail the wait */
        RtlFreeHeap(CsrHeap, 0, WaitBlock);
        CsrReleaseWaitLock();
        return FALSE;
    }

    /* Insert the wait in the queue */
    InsertTailList(WaitList, &WaitBlock->WaitList);

    /* Insert the User Wait too, if one was given */
    if (UserWaitList) InsertTailList(UserWaitList, &WaitBlock->UserWaitList);

    /* Return */
    CsrReleaseWaitLock();
    return TRUE;
}
Beispiel #2
0
/*++
 * @name CsrDereferenceWait
 * @implemented NT4
 *
 * The CsrDereferenceWait routine derefences a CSR Wait Block.
 *
 * @param WaitList
 *        Pointer to the Wait List associated to the wait.

 * @return None.
 *
 * @remarks None.
 *
 *--*/
VOID
NTAPI
CsrDereferenceWait(IN PLIST_ENTRY WaitList)
{
    PLIST_ENTRY NextEntry;
    PCSR_WAIT_BLOCK WaitBlock;

    /* Acquire the Process and Wait Locks */
    CsrAcquireProcessLock();
    CsrAcquireWaitLock();

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

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

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

        /* Check if there's no Wait Routine */
        if (!WaitBlock->WaitFunction)
        {
            /* Remove it from the Wait List */
            if (WaitBlock->WaitList.Flink)
            {
                RemoveEntryList(&WaitBlock->WaitList);
            }

            /* Remove it from the User Wait List */
            if (WaitBlock->UserWaitList.Flink)
            {
                RemoveEntryList(&WaitBlock->UserWaitList);
            }

            /* Dereference the thread waiting on it */
            CsrDereferenceThread(WaitBlock->WaitThread);

            /* Free the block */
            RtlFreeHeap(CsrHeap, 0, WaitBlock);
        }
    }

    /* Release the locks */
    CsrReleaseWaitLock();
    CsrReleaseProcessLock();
}
Beispiel #3
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;
}
Beispiel #4
0
/*++
 * @name CsrMoveSatisfiedWait
 * @implemented NT5
 *
 * The CsrMoveSatisfiedWait routine moves satisfied waits from a wait list
 * to another list entry.
 *
 * @param NewEntry
 *        Pointer to a list entry where the satisfied waits will be added.
 *
 * @param WaitList
 *        Pointer to a list entry to analyze for satisfied waits.
 *
 * @return None.
 *
 * @remarks None.
 *
 *--*/
VOID
NTAPI
CsrMoveSatisfiedWait(IN PLIST_ENTRY NewEntry,
                     IN PLIST_ENTRY WaitList)
{
    PLIST_ENTRY NextEntry;
    PCSR_WAIT_BLOCK WaitBlock;

    /* 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)
        {
            /* Remove it from the Wait Block Queue */
            RemoveEntryList(&WaitBlock->WaitList);

            /* Insert the new entry */
            InsertTailList(&WaitBlock->WaitList, NewEntry);
        }
    }

    /* Release the wait lock */
    CsrReleaseWaitLock();
}
Beispiel #5
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;
}