Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problem with accessing Queue from worker thread

0 views
Skip to first unread message

Daniel Stevenson

unread,
Mar 21, 2005, 7:48:35 PM3/21/05
to
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
}
//--------------------------------------------------------------------------
-


Eelke

unread,
Mar 22, 2005, 2:29:34 AM3/22/05
to
You declared the queue in the header which causes each cpp which
includes this header to get its own copy. Change the declaration to

extern TLogQueue<LogStruct> LogQueue;

and put

TLogQueue<LogStruct> LogQueue;

in one cpp.

Eelke

Daniel Stevenson

unread,
Mar 22, 2005, 3:59:34 PM3/22/05
to
Thank you very much, I thought I needed an extern declaration which I tried
but i wasn't declaring the object in the cpp file correctly.

Thanks heaps, its all working now.

"Eelke" <e.k...@mplussoftware.nl> wrote in message
news:423fc937$1...@newsgroups.borland.com...

Mark Guerrieri

unread,
Mar 31, 2005, 5:57:21 PM3/31/05
to
FYI- have a look at TCriticalSection (or TCOMCriticalSection) for a pre-made
critical section class...

Mark

"Daniel Stevenson" <d.ste...@ocreage.com.au> wrote in message
news:42408739$1...@newsgroups.borland.com...

Daniel Stevenson

unread,
Apr 1, 2005, 1:33:21 AM4/1/05
to
Thanks,

I wish I knew about that earlier...at least I've learnt something from all
of this.

"Mark Guerrieri" <mguerrieri@nospam_cmsgrp.com> wrote in message
news:424c8049$1...@newsgroups.borland.com...

Thomas Maeder [TeamB]

unread,
Apr 1, 2005, 10:30:32 AM4/1/05
to

Please direct your browser at http://info.borland.com/newsgroups/ and
read the newsgroup guidelines. One of them asks us not to quote entire
posts we are following up to; instead, please trim the quotes to the
parts relevant for your reply. Thanks!
0 new messages