Windows2003-3790/inetsrv/iis/svcs/smtp/server/queue.cxx
2020-09-30 16:53:55 +02:00

259 lines
4.9 KiB
C++

/*++
Copyright (c) 1994 Microsoft Corporation
Module Name :
queue.cxx
Abstract:
Implements a queue
Author:
Rohan Phillips ( Rohanp ) 11-Dec-1995
Project:
SMTP Server DLL
Functions Exported:
Revision History:
--*/
/************************************************************
* Include Headers
************************************************************/
#define INCL_INETSRV_INCS
#include "smtpinc.h"
#include "remoteq.hxx"
/*++
Name :
PERSIST_QUEUE::InitializeQueue
Description:
This function initializes all the class
member functions.
Arguments:
pszQueueName - Name of the on disk queue
Flags - Queue flags
Retry - How long we should retry failed deliveries
FlushQ - How often we should flush the queue to disk
Returns:
TRUE if all memory allocations and all I/O operations pass
FALSE otherwise
--*/
BOOL PERSIST_QUEUE::InitializeQueue (void)
{
TraceFunctEnterEx((LPARAM)this, "PERSIST_QUEUE::InitializeQueue");
// Now, initialize the queue structure:
m_QData.Entries = 0;
m_QData.RetryInterval = 0;
m_QData.StoreInterval = 0;
m_QData.Flags = 0;
m_QData.LastStore = (LONGLONG) 0;
//create the thread that processes things out of the
//the queue
DWORD ThreadId;
DWORD Loop = 0;
for (Loop = 0; Loop < m_NumThreads; Loop++)
{
m_ThreadHandle[Loop] = CreateThread (NULL, 0, PERSIST_QUEUE::QueueThreadRoutine, this, 0, &ThreadId);
if (m_ThreadHandle[Loop] == NULL)
{
TraceFunctLeaveEx((LPARAM)this);
return FALSE;
}
}
TraceFunctLeaveEx((LPARAM)this);
return TRUE;
}
/*++
Name :
PERSIST_QUEUE::CreateQueue
Description:
This is the static member function that creates the Queue
Arguments:
Qtype - the type of queue to create (i.e Local, Remote, etc.)
Returns:
TRUE if all memory allocations and all I/O operaations pass
FALSE otherwise
--*/
PERSIST_QUEUE * PERSIST_QUEUE::CreateQueue(QUEUE_TYPE Qtype, SMTP_SERVER_INSTANCE * pSmtpInst)
{
PERSIST_QUEUE * pQueue = NULL;
_ASSERT (pSmtpInst != NULL);
if(Qtype == REMOTEQ)
{
pQueue = new REMOTE_QUEUE(pSmtpInst);
if(pQueue)
{
pQueue->SetNumThreads(pSmtpInst->GetMaxRemoteQThreads());
}
else
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return(NULL);
}
}
else
{
_ASSERT(FALSE);
return NULL;
}
//initialize the queue
if(!pQueue->InitializeQueue())
{
delete pQueue;
pQueue = NULL;
}
return pQueue;
}
/*++
Name :
PERSIST_QUEUE::ProcessQueueEvents
Description:
This is the virtual process function
that all derived classes must override
This function is different depending on
what it is suppose to do. Take a look
at localq.cxx and remoteq.cxx for examples.
Arguments:
Returns:
Always TRUE
--*/
BOOL PERSIST_QUEUE::ProcessQueueEvents(ISMTPConnection *pISMTPConnection)
{
return TRUE;
}
/*++
Name :
PERSIST_QUEUE::FlushQueueEvents
Description:
This function deletes all entries from the queue
Arguments:
Returns:
--*/
void PERSIST_QUEUE::FlushQueueEvents(void)
{
PLIST_ENTRY pEntry;
PQUEUE_ENTRY pQEntry;
TraceFunctEnterEx((LPARAM)this, "PERSIST_QUEUE::FlushQueueEvents");
_ASSERT (GetParentInst() != NULL);
LockQ();
//delete all entries from the list
while(!IsListEmpty (&m_QHead))
{
GetParentInst()->StopHint();
pEntry = RemoveHeadList (&m_QHead);
pQEntry = CONTAINING_RECORD( pEntry, PERSIST_QUEUE_ENTRY, m_QEntry);
pQEntry->BeforeDelete();
delete pQEntry;
}
//reset the stop hint
GetParentInst()->SetStopHint(2);
UnLockQ();
TraceFunctLeaveEx((LPARAM)this);
}
/*++
Name :
PERSIST_QUEUE::QueueThreadRoutine
Description:
This function is the static member
function that gets passed to CreateThread
to initialize the queue.
Arguments:
A pointer to a PERSIST_QUEUE
Returns:
--*/
DWORD WINAPI PERSIST_QUEUE::QueueThreadRoutine(void * ThisPtr)
{
PQUEUE QueuePtr = (PQUEUE) ThisPtr;
HRESULT hr = S_OK;
ISMTPConnection *pISMTPConnection = NULL;
TraceFunctEnterEx((LPARAM)QueuePtr, "PERSIST_QUEUE::QueueThreadRoutine");
while(TRUE)
{
pISMTPConnection = NULL;
hr = QueuePtr->GetParentInst()->GetConnManPtr()->GetNextConnection(&pISMTPConnection);
if(!FAILED(hr))
{
//call the virtual process function
QueuePtr->ProcessQueueEvents(pISMTPConnection);
//if we are shutting down, break out of the loop
if (QueuePtr->GetParentInst()->IsShuttingDown())
goto Out;
}
else
{
//if we are shutting down, break out of the loop
if (QueuePtr->GetParentInst()->IsShuttingDown())
goto Out;
}
}
Out:
TraceFunctLeaveEx((LPARAM)QueuePtr);
return 1;
}