_SHARED MEMORY AND MESSAGE QUEUES_ by Richard B. Lam Listing One // **************************************************************************** // Module: ipcshmem.h -- Author: Dick Lam // Purpose: C++ class header file for ipcSharedMemory // Notes: This is a base class. It is the interface class for creating and // accessing a memory block that is sharable between processes and threads. // **************************************************************************** #ifndef MODULE_ipcSharedMemoryh #define MODULE_ipcSharedMemoryh // forward declaration class osSharedMemory; // class declaration class ipcSharedMemory { friend class osSharedMemory; public: // constructor and destructor ipcSharedMemory(const char *name, // unique name for creating block long blocksize); // requested size (in bytes) ipcSharedMemory(const char *name); // name of block to open virtual ~ipcSharedMemory(); // methods for getting memory block parameters [name, pointer to the block, // and whether this is the owner (creator) of the block] char *Name() const; void *Pointer() const; int Owner() const; // class version and object state data types enum version { MajorVersion = 1, MinorVersion = 0 }; enum state { good = 0, bad = 1, badname = 2, notfound = 3 }; // methods to get the object state inline int rdstate() const { return myState; } inline int operator!() const { return(myState != good); } protected: osSharedMemory *myImpl; // implementation state myState; // (object state (good, bad, etc.) private: // private copy constructor and operator= (define these and make them // public to enable copy and assignment of the class) ipcSharedMemory(const ipcSharedMemory&); ipcSharedMemory& operator=(const ipcSharedMemory&); }; #endif Listing Two // **************************************************************************** // Module: ipcshmem.C -- Author: Dick Lam // Purpose: C++ class source file for ipcSharedMemory // Notes: This is a base class. It is the interface class for creating and // accessing a memory block that is sharable between processes and threads. // **************************************************************************** #include "ipcshmem.h" #include "osshmem.h" // **************************************************************************** // ipcSharedMemory - constructor for creating ipcSharedMemory::ipcSharedMemory(const char *name, long blocksize) { // init instance variables myState = good; myImpl = new osSharedMemory(this, name, blocksize); if (!myImpl) myState = bad; } // ---------------------------------------------------------------------------- // ipcSharedMemory - constructor for accessing ipcSharedMemory::ipcSharedMemory(const char *name) { // init instance variables myState = good; myImpl = new osSharedMemory(this, name); if (!myImpl) myState = bad; } // ---------------------------------------------------------------------------- // ~ipcSharedMemory - destructor ipcSharedMemory::~ipcSharedMemory() { delete myImpl; } // ---------------------------------------------------------------------------- // Name - returns the name of the memory block char *ipcSharedMemory::Name() const { if (!myImpl) return 0; return myImpl->Name(); } // ---------------------------------------------------------------------------- // Pointer - returns a pointer to the start of the memory block void *ipcSharedMemory::Pointer() const { if (!myImpl) return 0; return myImpl->Pointer(); } // ---------------------------------------------------------------------------- // Owner - returns 1 if this is the owner (creator), and 0 otherwise int ipcSharedMemory::Owner() const { if (!myImpl) return 0; return myImpl->Owner(); } Listing Three // **************************************************************************** // Module: osshmem.h -- Author: Dick Lam // Purpose: C++ class header file for osSharedMemory // Notes: This is a base class. It contains general implementation methods // for memory blocks shared between processes and threads. // **************************************************************************** #ifndef MODULE_osSharedMemoryh #define MODULE_osSharedMemoryh #include "ipcshmem.h" // class declaration class osSharedMemory { public: // constructor and destructor osSharedMemory(ipcSharedMemory *interface,const char *name,long blocksize); osSharedMemory(ipcSharedMemory *interface, const char *name); virtual ~osSharedMemory(); // methods for getting memory block parameters [name, pointer to the block, // and whether this is the owner (creator) of the block] char *Name() const; void *Pointer() const; int Owner() const; protected: ipcSharedMemory *myInterface; // pointer to the interface instance unsigned long myID; // id of memory block char *myName; // shared memory block name int isOwner; // flag indicating owner void *myBlock; // pointer to the memory block // methods for handling the memory block void CreateBlock(long blocksize); void OpenBlock(); void CloseBlock(); private: // private copy constructor and operator= (define these and make them // public to enable copy and assignment of the class) osSharedMemory(const osSharedMemory&); osSharedMemory& operator=(const osSharedMemory&); }; #endif Listing Four // **************************************************************************** // Module: ipcqueue.h -- Author: Dick Lam // Purpose: C++ class header file for ipcMessageQueue // Notes: This is a base class. It is the interface class for creating and // accessing a message queue that handles messages between processes. // **************************************************************************** #ifndef MODULE_ipcMessageQueueh #define MODULE_ipcMessageQueueh // forward declaration class osMessageQueue; // class declaration class ipcMessageQueue { friend class osMessageQueue; public: // constructor and destructor ipcMessageQueue(const char *name); // unique name to create queue ipcMessageQueue(const char *name, // name of queue to open unsigned long powner); // process id of queue owner virtual ~ipcMessageQueue(); // methods for accessing the queue and queue parameters [name, queue id, // queue owner process id, and whether this is the owner (creator)] char *Name() const; unsigned long ID() const; unsigned long Pid() const; int Owner() const; // read/write methods for the queue (only a queue owner may read from // the queue, and only queue clients may write to a queue) virtual int Read(void *data, long datasize, int wait = 0); virtual int Write(void *data, long datasize); // methods to examine and remove messages from the queue (owner only) virtual unsigned long Peek(); virtual int Purge(); // class version and object state data types enum version { MajorVersion = 1, MinorVersion = 0 }; enum state { good = 0, bad = 1, badname = 2, notfound = 3, notowner = 4, notclient = 5, readerror = 6, writeerror = 7, badargument = 8 }; // methods to get the object state inline int rdstate() const { return myState; } inline int operator!() const { return(myState != good); } protected: osMessageQueue *myImpl; // implementation state myState; // (object state (good, bad, etc.) private: // private copy constructor and operator= (define these and make them // public to enable copy and assignment of the class) ipcMessageQueue(const ipcMessageQueue&); ipcMessageQueue& operator=(const ipcMessageQueue&); }; #endif Listing Five // **************************************************************************** // Module: ipcqueue.C -- Author: Dick Lam // Purpose: C++ class source file for ipcMessageQueue // Notes: This is a base class. It is the interface class for creating and // accessing a message queue that handles messages between processes. // **************************************************************************** #include "ipcqueue.h" #include "osqueue.h" // **************************************************************************** // ipcMessageQueue - constructor for server ipcMessageQueue::ipcMessageQueue(const char *name) { // init instance variables myState = good; myImpl = new osMessageQueue(this, name); if (!myImpl) myState = bad; } // ---------------------------------------------------------------------------- // ipcMessageQueue - constructor for clients ipcMessageQueue::ipcMessageQueue(const char *name, unsigned long powner) { // init instance variables myState = good; myImpl = new osMessageQueue(this, name, powner); if (!myImpl) myState = bad; } // ---------------------------------------------------------------------------- // ~ipcMessageQueue - destructor ipcMessageQueue::~ipcMessageQueue() { delete myImpl; } // ---------------------------------------------------------------------------- // Name - returns the name of the queue char *ipcMessageQueue::Name() const { if (!myImpl) return 0; return myImpl->Name(); } // ---------------------------------------------------------------------------- // ID - returns the queue id unsigned long ipcMessageQueue::ID() const { if (!myImpl) return 0L; return myImpl->ID(); } // ---------------------------------------------------------------------------- // Pid - returns the process id of the Queue owner unsigned long ipcMessageQueue::Pid() const { if (!myImpl) return 0L; return myImpl->Pid(); } // ---------------------------------------------------------------------------- // Owner - returns 1 if this is the owner (creator), and 0 otherwise int ipcMessageQueue::Owner() const { if (!myImpl) return 0; return myImpl->Owner(); } // ---------------------------------------------------------------------------- // Read - reads a message from the queue (queue owner only) int ipcMessageQueue::Read(void *data, long datasize, int wait) { if (!myImpl) return bad; return myImpl->Read(data, datasize, wait); } // ---------------------------------------------------------------------------- // Write - writes a message to the queue (queue clients only) int ipcMessageQueue::Write(void *data, long datasize) { if (!myImpl) return bad; return myImpl->Write(data, datasize); } // ---------------------------------------------------------------------------- // Peek - returns the number of entries in the queue unsigned long ipcMessageQueue::Peek() { if (!myImpl) return 0L; return myImpl->Peek(); } // ---------------------------------------------------------------------------- // Purge - removes all entries from the queue int ipcMessageQueue::Purge() { if (!myImpl) return bad; return myImpl->Purge(); } Listing Six // **************************************************************************** // Module: osqueue.h -- Author: Dick Lam // Purpose: C++ class header file for osMessageQueue // Notes: This is a base class. It contains general implementation methods // for message queues for sending messages between processes. // **************************************************************************** #ifndef MODULE_osMessageQueueh #define MODULE_osMessageQueueh #include "ipcqueue.h" // forward declaration class ipcEventSemaphore; // class declaration class osMessageQueue { public: // constructors and destructor osMessageQueue(ipcMessageQueue *interface, const char *name); osMessageQueue(ipcMessageQueue *interface, const char *name, unsigned long powner); virtual ~osMessageQueue(); // methods for accessing the queue and queue parameters [name, queue id, // queue owner process id, and whether this is the owner (creator)] char *Name() const; unsigned long ID() const; unsigned long Pid() const; int Owner() const; // read/write methods for the queue (only a queue owner may read from // the queue, and only queue clients may write to a queue) virtual int Read(void *data, long datasize, int wait); virtual int Write(void *data, long datasize); // methods to examine and remove messages from the queue virtual unsigned long Peek(); virtual int Purge(); protected: ipcMessageQueue *myInterface; // pointer to the interface instance unsigned long myPid; // process id of queue owner unsigned long myID; // id of queue char *myName; // queue name int isOwner; // flag indicating owner ipcEventSemaphore *mySem; // required for OS/2 only // methods for handling the message queue void CreateQueue(); void OpenQueue(); void CloseQueue(); private: // private copy constructor and operator= (define these and make them // public to enable copy and assignment of the class) osMessageQueue(const osMessageQueue&); osMessageQueue& operator=(const osMessageQueue&); }; #endif