260 lines
4.7 KiB
C++
260 lines
4.7 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"
|
|
#include "timemath.h"
|
|
|
|
/*++
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
|
|
|