📄 queuecontainer.cpp
字号:
//---------------------------------------------------------------------------
//
// QueueContainer.cpp
//
// SUBSYSTEM:
// Monitoring process creation and termination
//
// MODULE:
// Implement a multithreaded thread safe queue
//
// DESCRIPTION:
//
// AUTHOR: Ivo Ivanov
//
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
// Includes
//
//---------------------------------------------------------------------------
#include "stdafx.h"
#include "common.h"
#include ".\queuecontainer.h"
//---------------------------------------------------------------------------
//
// class CQueueContainer
//
//---------------------------------------------------------------------------
//
// Queue's constructor
//
CQueueContainer::CQueueContainer(CCallbackHandler* pHandler):
m_pHandler(pHandler),
m_pMonitorThread(NULL)
{
// Create the monitoring mutex
m_mtxMonitor = ::CreateMutex(NULL, FALSE, NULL);
assert(NULL != m_mtxMonitor);
// Create a thread for picking up posted in the queue item notifications
m_pQueueReadThread = new CQueueReadThread(
TEXT("{4EA19E49-1E3F-48da-AE16-2F2FD6A11F59}"),
this
);
// and if the driver can be opened activate the monitoring
// thread
m_pMonitorThread = new CDrvEventThread(
TEXT("{30F8934F-F57F-4ced-93A6-AF68CD0F6E79}"),
this
);
}
//
// Queue's destructor
//
CQueueContainer::~CQueueContainer()
{
StopMonitor();
delete m_pMonitorThread;
delete m_pQueueReadThread;
if (NULL != m_mtxMonitor)
::CloseHandle(m_mtxMonitor);
}
//
// Insert data into the queue
//
BOOL CQueueContainer::Append(const QUEUED_ITEM& element)
{
BOOL bResult = FALSE;
bResult = ( WAIT_OBJECT_0 == ::WaitForSingleObject(m_mtxMonitor, INFINITE) );
if (bResult)
{
//
// Add it to the STL queue
//
m_Queue.push_back(element);
//
// Notify the waiting thread that there is
// available element in the queue for processing
//
m_pQueueReadThread->EventNotify(true);
}
::ReleaseMutex(m_mtxMonitor);
return bResult;
}
//
// Implement specific behavior when kernel mode driver notifies
// the user-mode app
//
void CQueueContainer::DoOnProcessCreatedTerminated()
{
QUEUED_ITEM element;
// Initially we have at least one element for processing
BOOL bRemoveFromQueue = TRUE;
while (bRemoveFromQueue)
{
DWORD dwResult = ::WaitForSingleObject( m_mtxMonitor, INFINITE );
if (WAIT_OBJECT_0 == dwResult)
{
bRemoveFromQueue = (m_Queue.size() > 0);
// Is there anything in the queue
if (bRemoveFromQueue)
{
// Get the element from the queue
element = m_Queue.front();
m_Queue.pop_front();
} // if
else
{
// Let's make sure that the event hasn't been
// left in signaled state if there are no items
// in the queue
//
m_pQueueReadThread->EventNotify(false);
}
} // if
::ReleaseMutex(m_mtxMonitor);
// Process it only there is an element that has
// been picked up
if (bRemoveFromQueue)
m_pHandler->OnProcessEvent( &element, m_pvParam );
else
break;
} // while
}
//
// Set an external parameter, thus we could take the advantage
// of it later on in the callback routine
//
void CQueueContainer::SetExternalParam(PVOID pvParam)
{
m_pvParam = pvParam;
}
BOOL CQueueContainer::StartMonitor(void)
{
BOOL bResult;
bResult = m_pQueueReadThread->SetActive( TRUE );
if( !bResult )
{
return bResult;
}
bResult = m_pMonitorThread->SetActive(TRUE);
if( !bResult )
{
m_pQueueReadThread->SetActive(FALSE);
return bResult;
}
while( !m_pQueueReadThread->GetIsActive() || !m_pMonitorThread->GetIsActive() )
{
::Sleep(20);
}
return TRUE;
}
void CQueueContainer::StopMonitor(void)
{
m_pMonitorThread->SetActive(FALSE);
m_pQueueReadThread->SetActive(FALSE);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -