mirror of
https://github.com/reactos/reactos.git
synced 2025-08-07 07:03:06 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
436
subsystems/win32/csrsrv/wait.c
Normal file
436
subsystems/win32/csrsrv/wait.c
Normal file
|
@ -0,0 +1,436 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Client/Server Runtime SubSystem
|
||||
* FILE: subsystems/win32/csrsrv/wait.c
|
||||
* PURPOSE: CSR Server DLL Wait Implementation
|
||||
* PROGRAMMERS: Emanuele Aliberti
|
||||
* Alex Ionescu (alex@relsoft.net)
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "srv.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* DATA ***********************************************************************/
|
||||
|
||||
RTL_CRITICAL_SECTION CsrWaitListsLock;
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
/*++
|
||||
* @name CsrInitializeWait
|
||||
*
|
||||
* The CsrInitializeWait routine initializes a CSR Wait Object.
|
||||
*
|
||||
* @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 NewWaitBlock
|
||||
* Pointed to the initialized CSR Wait Block for this wait.
|
||||
*
|
||||
* @return TRUE in case of success, FALSE otherwise.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CsrInitializeWait(IN CSR_WAIT_FUNCTION WaitFunction,
|
||||
IN PCSR_THREAD CsrWaitThread,
|
||||
IN OUT PCSR_API_MESSAGE WaitApiMessage,
|
||||
IN PVOID WaitContext,
|
||||
OUT PCSR_WAIT_BLOCK *NewWaitBlock)
|
||||
{
|
||||
ULONG Size;
|
||||
PCSR_WAIT_BLOCK WaitBlock;
|
||||
|
||||
/* Calculate the size of the wait block */
|
||||
Size = sizeof(CSR_WAIT_BLOCK) -
|
||||
sizeof(WaitBlock->WaitApiMessage) +
|
||||
WaitApiMessage->Header.u1.s1.TotalLength;
|
||||
|
||||
/* Allocate the Wait Block */
|
||||
WaitBlock = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Size);
|
||||
if (!WaitBlock)
|
||||
{
|
||||
/* Fail */
|
||||
WaitApiMessage->Status = STATUS_NO_MEMORY;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Initialize it */
|
||||
WaitBlock->Size = Size;
|
||||
WaitBlock->WaitThread = CsrWaitThread;
|
||||
WaitBlock->WaitContext = WaitContext;
|
||||
WaitBlock->WaitFunction = WaitFunction;
|
||||
WaitBlock->WaitList.Flink = NULL;
|
||||
WaitBlock->WaitList.Blink = NULL;
|
||||
|
||||
/* Copy the message */
|
||||
RtlCopyMemory(&WaitBlock->WaitApiMessage,
|
||||
WaitApiMessage,
|
||||
WaitApiMessage->Header.u1.s1.TotalLength);
|
||||
|
||||
/* Return the block */
|
||||
*NewWaitBlock = WaitBlock;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name CsrNotifyWaitBlock
|
||||
*
|
||||
* The CsrNotifyWaitBlock routine calls the wait function for a registered
|
||||
* CSR Wait Block, and replies to the attached CSR API Message, if any.
|
||||
*
|
||||
* @param WaitBlock
|
||||
* Pointer to the CSR Wait Block.
|
||||
*
|
||||
* @param WaitList
|
||||
* Pointer to the wait list for this wait.
|
||||
*
|
||||
* @param WaitArgument[1-2]
|
||||
* User-defined values to pass to the wait function.
|
||||
*
|
||||
* @param WaitFlags
|
||||
* Wait flags for this wait.
|
||||
*
|
||||
* @param DereferenceThread
|
||||
* Specifies whether the CSR Thread should be dereferenced at the
|
||||
* end of this wait.
|
||||
*
|
||||
* @return TRUE in case of success, FALSE otherwise.
|
||||
*
|
||||
* @remarks After a wait block is notified, the wait function becomes invalid.
|
||||
*
|
||||
*--*/
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CsrNotifyWaitBlock(IN PCSR_WAIT_BLOCK WaitBlock,
|
||||
IN PLIST_ENTRY WaitList,
|
||||
IN PVOID WaitArgument1,
|
||||
IN PVOID WaitArgument2,
|
||||
IN ULONG WaitFlags,
|
||||
IN BOOLEAN DereferenceThread)
|
||||
{
|
||||
/* Call the wait function */
|
||||
if (WaitBlock->WaitFunction(WaitList,
|
||||
WaitBlock->WaitThread,
|
||||
&WaitBlock->WaitApiMessage,
|
||||
WaitBlock->WaitContext,
|
||||
WaitArgument1,
|
||||
WaitArgument2,
|
||||
WaitFlags))
|
||||
{
|
||||
/* The wait is done, clear the block */
|
||||
WaitBlock->WaitThread->WaitBlock = NULL;
|
||||
|
||||
/* Check for captured arguments */
|
||||
if (WaitBlock->WaitApiMessage.CsrCaptureData)
|
||||
{
|
||||
/* Release them */
|
||||
CsrReleaseCapturedArguments(&WaitBlock->WaitApiMessage);
|
||||
}
|
||||
|
||||
/* Reply to the port */
|
||||
NtReplyPort(WaitBlock->WaitThread->Process->ClientPort,
|
||||
&WaitBlock->WaitApiMessage.Header);
|
||||
|
||||
/* Check if we should dereference the thread */
|
||||
if (DereferenceThread)
|
||||
{
|
||||
/* Remove it from the Wait List */
|
||||
if (WaitBlock->WaitList.Flink)
|
||||
{
|
||||
RemoveEntryList(&WaitBlock->WaitList);
|
||||
}
|
||||
|
||||
/* Dereference the thread */
|
||||
CsrDereferenceThread(WaitBlock->WaitThread);
|
||||
|
||||
/* Free the wait block */
|
||||
RtlFreeHeap(CsrHeap, 0, WaitBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The wait is complete, but the thread is being kept alive */
|
||||
WaitBlock->WaitFunction = NULL;
|
||||
}
|
||||
|
||||
/* The wait succeeded */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* The wait failed */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
/*++
|
||||
* @name CsrCreateWait
|
||||
* @implemented NT4
|
||||
*
|
||||
* The CsrCreateWait routine creates a CSR Wait.
|
||||
*
|
||||
* @param WaitList
|
||||
* Pointer to a wait list in which the wait will be added.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* Associate the newly created wait to the waiting thread */
|
||||
CsrWaitThread->WaitBlock = WaitBlock;
|
||||
|
||||
/* Insert the wait in the queue */
|
||||
InsertTailList(WaitList, &WaitBlock->WaitList);
|
||||
|
||||
/* Return */
|
||||
CsrReleaseWaitLock();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name CsrDereferenceWait
|
||||
* @implemented NT4
|
||||
*
|
||||
* The CsrDereferenceWait routine dereferences 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 (satisfied wait) */
|
||||
if (WaitBlock->WaitFunction == NULL)
|
||||
{
|
||||
/* Remove it from the Wait List */
|
||||
if (WaitBlock->WaitList.Flink)
|
||||
{
|
||||
RemoveEntryList(&WaitBlock->WaitList);
|
||||
}
|
||||
|
||||
/* Dereference the thread waiting on it */
|
||||
CsrDereferenceThread(WaitBlock->WaitThread);
|
||||
|
||||
/* Free the block */
|
||||
RtlFreeHeap(CsrHeap, 0, WaitBlock);
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the locks */
|
||||
CsrReleaseWaitLock();
|
||||
CsrReleaseProcessLock();
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name CsrMoveSatisfiedWait
|
||||
* @implemented NT5
|
||||
*
|
||||
* The CsrMoveSatisfiedWait routine moves satisfied waits from
|
||||
* a wait list to another list.
|
||||
*
|
||||
* @param DestinationList
|
||||
* Pointer to a list in which the satisfied waits will be added.
|
||||
*
|
||||
* @param WaitList
|
||||
* Pointer to the wait list whose satisfied wait blocks
|
||||
* will be moved away.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
NTAPI
|
||||
CsrMoveSatisfiedWait(IN PLIST_ENTRY DestinationList,
|
||||
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's no Wait Routine (satisfied wait) */
|
||||
if (WaitBlock->WaitFunction == NULL)
|
||||
{
|
||||
/* Remove it from the Wait Block Queue */
|
||||
RemoveEntryList(&WaitBlock->WaitList);
|
||||
|
||||
/* Insert the wait into the destination list */
|
||||
InsertTailList(DestinationList, &WaitBlock->WaitList);
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the wait lock */
|
||||
CsrReleaseWaitLock();
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name CsrNotifyWait
|
||||
* @implemented NT4
|
||||
*
|
||||
* The CsrNotifyWait routine notifies CSR Wait Blocks.
|
||||
*
|
||||
* @param WaitList
|
||||
* Pointer to the wait list whose wait blocks will be notified.
|
||||
*
|
||||
* @param NotifyAll
|
||||
* Whether or not we must notify all the waits.
|
||||
*
|
||||
* @param WaitArgument[1-2]
|
||||
* User-defined argument to pass on to the wait function.
|
||||
*
|
||||
* @return TRUE in case of success, FALSE otherwise.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CsrNotifyWait(IN PLIST_ENTRY WaitList,
|
||||
IN BOOLEAN NotifyAll,
|
||||
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 Routine */
|
||||
if (WaitBlock->WaitFunction != NULL)
|
||||
{
|
||||
/* Notify the Waiter */
|
||||
NotifySuccess |= CsrNotifyWaitBlock(WaitBlock,
|
||||
WaitList,
|
||||
WaitArgument1,
|
||||
WaitArgument2,
|
||||
0,
|
||||
FALSE);
|
||||
|
||||
/*
|
||||
* We've already done a wait, so leave unless
|
||||
* we want to notify all the waits...
|
||||
*/
|
||||
if (!NotifyAll) break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the wait lock and return */
|
||||
CsrReleaseWaitLock();
|
||||
return NotifySuccess;
|
||||
}
|
||||
|
||||
/* EOF */
|
Loading…
Add table
Add a link
Reference in a new issue