Article View: borland.public.cppbuilder.oodesign
Article #48Problem with accessing Queue from worker thread
From: Daniel Stevenson
Date: Tue, 22 Mar 2005 00:48
Date: Tue, 22 Mar 2005 00:48
364 lines
11007 bytes
11007 bytes
I've created a thread safe queue using the STL queue, in the main thread I
push objects onto the queue and within my thread I interrogate the queue to
see if the size increases and if so I then pop the object off and perform
something.
My problem seems to be simple in that I can't seem to access the same queue
pointer from within my thread as I do within my main thread.
In my main thread as I pop objects onto the queue, I can see the size
increase but whenever I interrogate the queue from the worker thread it
always returns zero....and I'm sure I'm doing something stupidly simple but
i can't seem to see what that is...can someone point out my stupidity.
I have summarized by code below...
...LogQueueSource.h file...
//--------------------------------------------------------------------------
-
#ifndef TLogQueueSourceH
#define TLogQueueSourceH
//--------------------------------------------------------------------------
-
#include <queue>
//--------------------------------------------------------------------------
-
//--------------------------------------------------------------------------
-
typedef struct LogStruct
{
long StatusType;
AnsiString Origin;
long Level;
AnsiString Description;
TDateTime DateStamp;
TDateTime TimeStamp;
AnsiString CallNumber;
AnsiString DisplayMessage;
long Priority;
long PagingID;
AnsiString Subject;
AnsiString Body;
long IndicationCode;
bool BreakThrough;
long ConfirmationType;
bool IsErase;
long TimeToLive;
bool AllowRemoteDelete;
} LogInfo;
//--------------------------------------------------------------------------
-
class CriticalSection
{
private:
CRITICAL_SECTION m_cs;
public:
CriticalSection()
{
::InitializeCriticalSection(&m_cs);
}
CriticalSection(const CriticalSection& rhs)
{
// ignore rhs
::InitializeCriticalSection(&m_cs);
}
~CriticalSection()
{
::DeleteCriticalSection(&m_cs);
}
CriticalSection& operator=(const CriticalSection& rhs)
{
// ignore rhs & do nothing
return *this;
}
void Enter()
{
::EnterCriticalSection(&m_cs);
}
void Leave()
{
::LeaveCriticalSection(&m_cs);
}
};
//--------------------------------------------------------------------------
-
class CriticalSectionLock
{
private:
CriticalSection& m_cs;
// unimplemented
CriticalSectionLock& operator=(const CriticalSectionLock&);
CriticalSectionLock(const CriticalSectionLock&);
public:
CriticalSectionLock(CriticalSection& cs)
: m_cs(cs)
{
m_cs.Enter();
}
~CriticalSectionLock()
{
m_cs.Leave();
}
};
//--------------------------------------------------------------------------
-
template <class T>
class TLogQueue
{
private:
std::queue<T> m_q;
CriticalSection m_cs;
public:
typedef T value_type;
// .. other typedefs as needed
void push(const value_type& v)
{
CriticalSectionLock lock(m_cs);
m_q.push(v);
}
void pop()
{
CriticalSectionLock lock(m_cs);
m_q.pop();
}
unsigned int size()
{
CriticalSectionLock lock(m_cs);
unsigned int size = m_q.size();
return size;
}
const value_type& front() const
{
return m_q.front();
}
const value_type& top() const
{
// CriticalSectionLock lock(m_cs);
return m_q.top();
}
};
//--------------------------------------------------------------------------
-
#endif
I don't think there is anything wrong with the above declaration, I included
this to reduce the number of questions in this area.
I think the problem is in how I've declared my queue but I'm having a brain
freeze and can't think straight to work out my problem as seen below.
....LoggingServiceSource.h...
//--------------------------------------------------------------------------
-
#ifndef LoggingServiceSourceH
#define LoggingServiceSourceH
//--------------------------------------------------------------------------
-
#include <SysUtils.hpp>
#include <Classes.hpp>
#include <SvcMgr.hpp>
#include <vcl.h>
#include "thdLoggingSource.h"
#include <OleServer.hpp>
#include <queue>
using namespace std;
//--------------------------------------------------------------------------
-
TLogQueue<LogStruct> LogQueue; //declaring my queue
//--------------------------------------------------------------------------
-
class TLoggingService : public TService
{
__published: // IDE-managed Components
TatSystemStatus *atSystemStatus;
TatPagingSubscription *atPagingSubscription;
void __fastcall atSystemStatusSystemStatus(TObject *Sender,
atSystemStatusType StatusType, BSTR Origin,
atSystemStatusLevel Level, BSTR Description);
void __fastcall atPagingSubscriptionPaging(TObject *Sender,
BSTR CallNumber, BSTR DisplayMessage, long Priority,
PagingInfoStruct *AdditionalInfo);
private: // User declarations
TLoggingThread *LoggingThread;
String ConnectionStatus;
void __fastcall UpdateServiceDescription(TService *Sender);
void __fastcall CreateWorkerThread();
void __fastcall CheckSystemStatus();
public: // User declarations
__fastcall TLoggingService(TComponent* Owner);
TServiceController __fastcall GetServiceController(void);
friend void __stdcall ServiceController(unsigned CtrlCode);
};
//--------------------------------------------------------------------------
-
extern PACKAGE TLoggingService *LoggingService;
//--------------------------------------------------------------------------
-
#endif
...LoggingServiceSource.cpp....
//--------------------------------------------------------------------------
-
#include "LoggingServiceSource.h"
#include <deque>
#include "LogQueueSource.h"
//--------------------------------------------------------------------------
-
#pragma package(smart_init)
#pragma resource "*.dfm"
TLoggingService *LoggingService;
//--------------------------------------------------------------------------
-
__fastcall TLoggingService::TLoggingService(TComponent* Owner)
: TService(Owner)
{
CreateWorkerThread();
CheckSystemStatus();
}
//--------------------------------------------------------------------------
-
TServiceController __fastcall TLoggingService::GetServiceController(void)
{
return (TServiceController) ServiceController;
}
//--------------------------------------------------------------------------
-
void __stdcall ServiceController(unsigned CtrlCode)
{
LoggingService->Controller(CtrlCode);
}
//--------------------------------------------------------------------------
-
void __fastcall TLoggingService::atSystemStatusSystemStatus(TObject *Sender,
atSystemStatusType StatusType, BSTR Origin,
atSystemStatusLevel Level, BSTR Description)
{
//log all this information in the queue
LogInfo NewLog;
NewLog.StatusType = StatusType;
NewLog.Origin = Origin;
NewLog.Level = Level;
NewLog.Description = Description;
NewLog.DateStamp = TDateTime::CurrentDate();
NewLog.TimeStamp = TDateTime::CurrentTime();
LogQueue.push(NewLog);
unsigned int size = LogQueue.size(); //this value is
incremented correctly after each push
}
//--------------------------------------------------------------------------
-
void __fastcall TLoggingService::CreateWorkerThread()
{
LoggingThread = new TLoggingThread(false);
LoggingThread->FreeOnTerminate = true;
LoggingThread->Resume();
}
//--------------------------------------------------------------------------
-
void __fastcall TLoggingService::CheckSystemStatus()
{
atSystemStatus->QueryConnectionStatus();
}
//--------------------------------------------------------------------------
-
all of the above seems to work fine (please ignore the fact that I will have
problems with my struct definition and what is actually stored on the queue,
I am more interested in that fact that when something is stored on the queue
I can see that from my worker thread as seem below...
...LoggingSource.h...
//--------------------------------------------------------------------------
-
#ifndef thdLoggingSourceH
#define thdLoggingSourceH
//--------------------------------------------------------------------------
-
#include <Classes.hpp>
#include "LogQueueSource.h"
//--------------------------------------------------------------------------
-
class TLoggingThread : public TThread
{
private:
void __fastcall ProcessQueueData();
protected:
void __fastcall Execute();
public:
__fastcall TLoggingThread(bool CreateSuspended);
};
//--------------------------------------------------------------------------
-
#endif
...LoggingSource.cpp...
//--------------------------------------------------------------------------
-
#include <vcl.h>
#pragma hdrstop
#include "thdLoggingSource.h"
#include "frmLoggingServiceSource.h"
#include "LogQueueSource.h"
#pragma package(smart_init)
//--------------------------------------------------------------------------
-
__fastcall TLoggingThread::TLoggingThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
//--------------------------------------------------------------------------
-
void __fastcall TLoggingThread::Execute()
{
while (!Terminated)
{
unsigned int size = LogQueue.size(); //this returns zero no
matter how big the queue is in the main thread
if (size > 0)
{
int i = 0;
i = i;
//ProcessQueueData();
}
else
{
Sleep(5000);
}
}
}
//--------------------------------------------------------------------------
-
void __fastcall TLoggingThread::ProcessQueueData()
{
LogInfo NewLog = LogQueue.front();
LogQueue.pop();
///do something here
}
//--------------------------------------------------------------------------
-
Technical Details
Message-ID:
<423f6b65@newsgroups.borland.com>Path:
arc1-ca.pugleaf.net!g2news1.google.com!news4.google.com!news.glorb.com!border1.nntp.dca.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!newshosting.com!nx02.iad01.newshosting.com!news-out.nntp.be!propagator2-sterling.newsfeeds.com!news-in.newsfeeds.com!in.nntp.be!caladan.landsraad.net!newsgroups.borland.com!not-for-mailShow Full Headers
Complete Article Headers
X-Google-Thread: 10db1e,62ae9303d665b63f,start X-Google-Attributes: gid10db1e,public X-Google-Language: ENGLISH,ASCII-7-bit From: "Daniel Stevenson" <d.stevenson@ocreage.com.au> Newsgroups: borland.public.cppbuilder.oodesign Subject: Problem with accessing Queue from worker thread Date: Tue, 22 Mar 2005 11:48:35 +1100 Lines: 370 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2800.1158 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165 NNTP-Posting-Host: 202.174.233.53 Message-ID: <423f6b65@newsgroups.borland.com> X-Trace: newsgroups.borland.com 1111452517 202.174.233.53 (21 Mar 2005 16:48:37 -0800) Path: arc1-ca.pugleaf.net!g2news1.google.com!news4.google.com!news.glorb.com!border1.nntp.dca.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!newshosting.com!nx02.iad01.newshosting.com!news-out.nntp.be!propagator2-sterling.newsfeeds.com!news-in.newsfeeds.com!in.nntp.be!caladan.landsraad.net!newsgroups.borland.com!not-for-mail