Windows-Server-2003/enduser/troubleshoot/tshoot/apgtspl.cpp

186 lines
3.7 KiB
C++

//
// MODULE: APGTSPL.CPP
//
// PURPOSE: Pool Queue shared variables
// Fully implement class PoolQueue
//
// PROJECT: Generic Troubleshooter DLL for Microsoft AnswerPoint
//
// COMPANY: Saltmine Creative, Inc. (206)-284-7511 support@saltmine.com
//
// AUTHOR: Roman Mach
//
// ORIGINAL DATE: 8-2-96
//
// NOTES:
// 1. Based on Print Troubleshooter DLL
//
// Version Date By Comments
//--------------------------------------------------------------------
// V0.1 - RM Original
// V3.0 9/21/98 JM Working on encapsulation
//
#pragma warning(disable:4786)
#include "stdafx.h"
#include "apgtspl.h"
#include "event.h"
#include "apgtscls.h"
#include "CharConv.h"
//
//
CPoolQueue::CPoolQueue() :
m_dwErr(0),
m_cInProcess(0),
m_timeLastAdd(0),
m_timeLastRemove(0)
{
::InitializeCriticalSection( &m_csQueueLock );
m_hWorkSem = CreateSemaphore(NULL,
0,
0x7fffffff,
NULL );
if (m_hWorkSem == NULL)
m_dwErr = EV_GTS_ERROR_POOL_SEMA;
}
//
//
CPoolQueue::~CPoolQueue()
{
if (m_hWorkSem)
::CloseHandle(m_hWorkSem);
while ( !m_WorkQueue.empty() )
{
delete m_WorkQueue.back();
m_WorkQueue.pop_back();
}
::DeleteCriticalSection( &m_csQueueLock );
}
void CPoolQueue::Lock()
{
::EnterCriticalSection( &m_csQueueLock );
}
void CPoolQueue::Unlock()
{
::LeaveCriticalSection( &m_csQueueLock );
}
//
//
DWORD CPoolQueue::GetStatus()
{
return m_dwErr;
}
// put it at the tail of the queue & Signal the pool threads there is work to be done
// OK if we're already locked when this is called; OK if we're not.
void CPoolQueue::PushBack(WORK_QUEUE_ITEM * pwqi)
{
Lock();
// Some data passed to thread just for statistical purposes
// Thread can pass this info back over web; we can't.
pwqi->GTSStat.dwQueueItems = GetTotalQueueItems();
pwqi->GTSStat.dwWorkItems = GetTotalWorkItems();
try
{
m_WorkQueue.push_back(pwqi);
time(&m_timeLastAdd);
// Signal the pool threads there is work to be done only if it was
// successfully added to the work queue.
::ReleaseSemaphore( m_hWorkSem, 1, NULL );
}
catch (exception& x)
{
CString str;
// Note STL exception in event log.
CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ );
CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(),
SrcLoc.GetSrcFileLineStr(),
CCharConversion::ConvertACharToString(x.what(), str),
_T(""),
EV_GTS_STL_EXCEPTION );
}
Unlock();
}
// Get the item at the front of the queue in order to act on it.
WORK_QUEUE_ITEM * CPoolQueue::GetWorkItem()
{
WORK_QUEUE_ITEM * pwqi;
Lock();
if ( !m_WorkQueue.empty() )
{
vector<WORK_QUEUE_ITEM *>::iterator it = m_WorkQueue.begin();
pwqi = *it;
m_WorkQueue.erase(it);
time(&m_timeLastRemove);
++m_cInProcess;
}
else
pwqi = NULL;
Unlock();
return pwqi;
}
// When we are totally done with a work item, reduce the count of those which are
// in process.
// Arbitrary, but acceptable, decision to track m_cInProcess in this class. JM 11/30/98
void CPoolQueue::DecrementWorkItems()
{
Lock();
--m_cInProcess;
Unlock();
}
// Called by a pool thread to wait for there to be something in this queue.
DWORD CPoolQueue::WaitForWork()
{
return ::WaitForSingleObject( m_hWorkSem, INFINITE );
}
// Arbitrary, but acceptable, decision to track m_cInProcess in this class. JM 11/30/98
DWORD CPoolQueue::GetTotalWorkItems()
{
Lock();
DWORD ret = m_cInProcess + GetTotalQueueItems();
Unlock();
return ret;
}
DWORD CPoolQueue::GetTotalQueueItems()
{
Lock();
DWORD ret = m_WorkQueue.size();
Unlock();
return ret;
}
time_t CPoolQueue::GetTimeLastAdd()
{
Lock();
time_t ret = m_timeLastAdd;
Unlock();
return ret;
}
time_t CPoolQueue::GetTimeLastRemove()
{
Lock();
time_t ret = m_timeLastRemove;
Unlock();
return ret;
}