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