threaded message queue in BCB

disclaimer

A multithreaded message queue is implemented with the help of events. One thread is only reading and anotherone is only writing. The aim was not preventing multiple access but suppress polling for a state.

the h file

//---------------------------------------------------------------------------
#ifndef MsgQueueH
#define MsgQueueH
//---------------------------------------------------------------------------
#include 
#include 
#include 
#include 
#include 
//---------------------------------------------------------------------------
class PACKAGE TMsgNode : public TObject
{
private:
 int fsize;
 int fdata;
 TMsgNode  *fnext;
 TMsgNode  *fprev;
protected:
 char __fastcall getitem(int index);
 void __fastcall setitem(int index, char u);
public:
//__property char data[int index]={read=getitem,write=setitem};
 __fastcall TMsgNode(int newsize);
 __fastcall TMsgNode();
 __fastcall ~TMsgNode();
__published:
__property int size={read=fsize,write=fsize};
__property int data={read=fdata,write=fdata};
__property TMsgNode *next={read=fnext,write=fnext};
__property TMsgNode *prev={read=fprev,write=fprev};
};

class PACKAGE TMsgQueue : public TObject
{
private:
 int fcount;
 TEvent * fNotEmpty;
 TMsgNode *fHead;
 TMsgNode *fTail;
protected:
public:
 __fastcall TMsgQueue();
 __fastcall ~TMsgQueue();
void __fastcall QueueIn(char * data, int size);
void __fastcall QueueOut(int &data, int &size);

__published:
__property int count={read=fcount};
__property TEvent * NotEmpty ={read=fNotEmpty,write=fNotEmpty};
};
//---------------------------------------------------------------------------
#endif

the cpp file

//---------------------------------------------------------------------------
#include 
#pragma hdrstop

#include "MsgQueue.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

//static inline void ValidCtrCheck(TMsgQueue *)
//{
//        new TMsgQueue(NULL);
//}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
 __fastcall TMsgNode::TMsgNode(int newsize)
{
 fsize=newsize;
 fdata=(int)malloc(newsize);
 fnext=NULL;
 fprev=NULL;
}
//---------------------------------------------------------------------------
__fastcall TMsgNode::TMsgNode()
{
 fsize=0;
 fdata=NULL;
 fnext=NULL;
 fprev=NULL;
}
//---------------------------------------------------------------------------
 __fastcall TMsgNode::~TMsgNode()
{
// free(fdata);
}
//---------------------------------------------------------------------------

__fastcall TMsgQueue::TMsgQueue()
        : TObject()
{
 fcount=0;
 fNotEmpty= new TEvent(NULL,false,false,"");
 fHead=NULL;
 fTail=NULL;
}
//---------------------------------------------------------------------------
namespace Msgqueue
{
        void __fastcall PACKAGE Register()
        {
                 TComponentClass classes[1] = {__classid(TMsgQueue)};
                 RegisterComponents("Samples", classes, 0);
        }
}
//---------------------------------------------------------------------------
//__fastcall TMsgQueue::TMsgQueue()
//{
// fcount=0;
// fNotEmpty= new TEvent(NULL,false,false,"");
// fHead=NULL;
// fTail=NULL;
//}
//---------------------------------------------------------------------------
__fastcall TMsgQueue::~TMsgQueue()
{
 int z;
 int n;

 while (fcount>0)
 { QueueOut(z,n);
   free((void*)z);
 }
 fNotEmpty->TEvent::~TEvent();
}
//---------------------------------------------------------------------------
void __fastcall TMsgQueue::QueueIn(char * data, int size)
{
 TMsgNode *u;
 u = new TMsgNode(size);
 Move((void*)data,(void*)u->data,size);
//u.dataptr=data;
 u->size=size;
 if (fHead==NULL)
  {
   fHead=u;
   fTail=u;
   fcount++;
  }
 else {
  u->next=fHead;
  fHead->prev=u;
  fHead=u;
  fcount++;
  }
 fNotEmpty->SetEvent();
}

//---------------------------------------------------------------------------
void __fastcall TMsgQueue::QueueOut(int &data, int &size)
{
 TMsgNode * u;
 int i;
 if (fTail !=NULL) {
  u=fTail;
  fTail=u->prev;
  if (fTail==NULL){fHead=NULL;}
  fcount--;
  data=u->data;
  size=u->size;
  if (fcount !=0) {fNotEmpty->SetEvent();}
 }
}
//---------------------------------------------------------------------------



my BCB
home

last updated: 29.june.01

Copyright (99,2001) Ing.Büro R.Tschaggelar