Windows2003-3790/termsrv/newclient/rdpdr/w32dispq.cpp
2020-09-30 16:53:55 +02:00

363 lines
6.5 KiB
C++

/*++
Copyright (c) 1998-2000 Microsoft Corporation
Module Name:
w32dispq.cpp
Abstract:
Contains the Win32 Operation Dispatch Object class,
W32DispatchQueue.
Enqueue at the head. Dequeue at the tail.
Author:
Tad Brockway (tadb) 4/19/99
Revision History:
--*/
#include <precom.h>
#define TRC_FILE "W32DispQ"
#include "w32dispq.h"
#include "drdbg.h"
///////////////////////////////////////////////////////////////
//
// W32DispatchQueue Methods
//
//
W32DispatchQueue::W32DispatchQueue()
/*++
Routine Description:
Constructor
Arguments:
initialSize - Initial number of elements in the queue.
Return Value:
NA
--*/
{
DC_BEGIN_FN("W32DispatchQueue::W32DispatchQueue");
//
// Not valid until initialized.
//
SetValid(FALSE);
DC_END_FN();
}
W32DispatchQueue::~W32DispatchQueue()
/*++
Routine Description:
Destructor
Arguments:
NA
Return Value:
NA
--*/
{
DC_BEGIN_FN("W32DispatchQueue::~W32DispatchQueue");
//
// Assert that the queue is empty.
//
ASSERT(_queue->GetCount() == 0);
//
// Release the "data ready" event.
//
if (_dataReadyEvent != NULL) {
CloseHandle(_dataReadyEvent);
}
//
// Release the queue instance.
//
if (_queue != NULL) {
delete _queue;
}
DC_END_FN();
}
DWORD W32DispatchQueue::Initialize()
/*++
Routine Description:
Initialize
Arguments:
Return Value:
ERROR_SUCCESS on success. Otherwise, an error code is returned.
--*/
{
DWORD result = ERROR_SUCCESS;
DC_BEGIN_FN("W32DispatchQueue::Initialize");
//
// Create the "data ready" event.
//
_dataReadyEvent = CreateEvent(
NULL, // no attribute.
FALSE, // auto reset.
FALSE, // initially not signalled.
NULL // no name.
);
if (_dataReadyEvent == NULL) {
result = GetLastError();
TRC_ERR((TB, _T("CreateEvent %ld."), result));
goto CLEANUPANDEXIT;
}
//
// Create the queue instance.
//
_queue = new DrQueue<QUEUEELEMENT>;
if (_queue == NULL) {
TRC_ERR((TB, _T("Can't instantiate DrQueue.")));
result = ERROR_NOT_ENOUGH_MEMORY;
goto CLEANUPANDEXIT;
}
result = _queue->Initialize();
if (result != ERROR_SUCCESS) {
delete _queue;
_queue = NULL;
goto CLEANUPANDEXIT;
}
SetValid(TRUE);
CLEANUPANDEXIT:
return result;
}
BOOL W32DispatchQueue::PeekNextEntry(
OPTIONAL OUT W32DispatchQueueFunc *func,
OPTIONAL OUT VOID **clientData
)
/*++
Routine Description:
Peek at the next entry in the queue without dequeueing.
Arguments:
func - Function associated with next element.
clientData - Client data associated with next element.
Return Value:
NA
--*/
{
BOOL result;
QUEUEELEMENT queueElement;
DC_BEGIN_FN("W32DispatchQueue::PeekNextEntry");
ASSERT(IsValid());
result = IsValid() && _queue->PeekNextEntry(queueElement);
if (result) {
if (func != NULL) {
*func = queueElement.func;
}
if (clientData != NULL) {
*clientData = queueElement.clientData;
}
}
DC_END_FN();
return result;
}
BOOL W32DispatchQueue::Dequeue(
OPTIONAL OUT W32DispatchQueueFunc *func,
OPTIONAL OUT VOID **clientData
)
/*++
Routine Description:
Grab the next queued operation out of the queue.
Arguments:
func - Function associated with next element.
clientData - Client data associated with next element.
Return Value:
TRUE if there was an element in the queue to be dequeued.
--*/
{
BOOL result;
QUEUEELEMENT element;
DC_BEGIN_FN("W32DispatchQueue::Dequeue");
ASSERT(IsValid());
result = IsValid() && _queue->Dequeue(element);
if (result) {
if (func != NULL) *func = element.func;
if (clientData != NULL) *clientData = element.clientData;
}
DC_END_FN();
return result;
}
BOOL W32DispatchQueue::Enqueue(
IN W32DispatchQueueFunc func,
OPTIONAL IN VOID *clientData
)
/*++
Routine Description:
Add an element to the queue in FIFO fashion.
Arguments:
func - Function associated with new element.
clientData - Client data associated with new element.
Return Value:
TRUE if the new element could be successfully queued. FALSE,
otherwise. If FALSE is returned then GetLastError() can be
used to retrieve the exact error code.
--*/
{
BOOL result;
QUEUEELEMENT element;
DC_BEGIN_FN("W32DispatchQueue::Enqueue");
ASSERT(IsValid());
element.func = func;
element.clientData = clientData;
result = IsValid() && _queue->Enqueue(element);
//
// Signal the data ready event if the enqueue succeeded.
//
if (result) {
SetEvent(_dataReadyEvent);
}
DC_END_FN();
return result;
}
BOOL W32DispatchQueue::Requeue(
IN W32DispatchQueueFunc func,
OPTIONAL IN VOID *clientData,
IN BOOL signalNewData
)
/*++
Routine Description:
Requeue an element at the tail of the queue in LIFO fashion.
Arguments:
func - Function associated with new element.
clientData - Client data associated with new element.
signalNewData - If TRUE then the waitable object associated
with this queue will be signalled.
Return Value:
TRUE if the new element could be successfully queued. FALSE,
otherwise. If FALSE is returned then GetLastError() can be
used to retrieve the exact error code.
--*/
{
DC_BEGIN_FN("W32DispatchQueue::Requeue");
BOOL result;
QUEUEELEMENT element;
ASSERT(IsValid());
element.func = func;
element.clientData = clientData;
result = IsValid() && _queue->Requeue(element);
//
// Signal the data ready event if the enqueue succeeded.
//
if (result && signalNewData) {
SetEvent(_dataReadyEvent);
}
DC_END_FN();
return result;
}