🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.oodesign
6 messages
6 total messages Started by Daniel Stevenson Tue, 22 Mar 2005 00:48
Problem with accessing Queue from worker thread
#48
Author: Daniel Stevenson
Date: Tue, 22 Mar 2005 00:48
364 lines
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
}
//--------------------------------------------------------------------------
-
Re: Problem with accessing Queue from worker thread
#49
Author: Eelke
Date: Tue, 22 Mar 2005 07:29
70 lines
3471 bytes
> 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
> 
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
Re: Problem with accessing Queue from worker thread
#50
Author: Daniel Stevenson
Date: Tue, 22 Mar 2005 20:59
85 lines
3967 bytes
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.klein@mplussoftware.nl> wrote in message
news:423fc937$1@newsgroups.borland.com...
>
> > 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
> >
> 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
Re: Problem with accessing Queue from worker thread
#53
Author: Mark Guerrieri
Date: Thu, 31 Mar 2005 22:57
101 lines
4320 bytes
FYI- have a look at TCriticalSection (or TCOMCriticalSection) for a pre-made
critical section class...

Mark

"Daniel Stevenson" <d.stevenson@ocreage.com.au> wrote in message
news:42408739$1@newsgroups.borland.com...
> 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.klein@mplussoftware.nl> wrote in message
> news:423fc937$1@newsgroups.borland.com...
> >
> > > 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
> > >
> > 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
>
>
Re: Problem with accessing Queue from worker thread
#54
Author: Daniel Stevenson
Date: Fri, 01 Apr 2005 06:33
119 lines
4771 bytes
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...
> FYI- have a look at TCriticalSection (or TCOMCriticalSection) for a
pre-made
> critical section class...
>
> Mark
>
> "Daniel Stevenson" <d.stevenson@ocreage.com.au> wrote in message
> news:42408739$1@newsgroups.borland.com...
> > 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.klein@mplussoftware.nl> wrote in message
> > news:423fc937$1@newsgroups.borland.com...
> > >
> > > > 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
> > > >
> > > 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
> >
> >
>
>
Re: Problem with accessing Queue from worker thread
#55
Author: Thomas Maeder [TeamB]
Date: Fri, 01 Apr 2005 15:30
5 lines
1456 bytes
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!
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads