Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

ipcplus.h

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2002 by LifeLine Networks bv.
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU Library General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018  
00024 #ifndef H_include_IPC
00025 #define H_include_IPC
00026 #ifdef HAVE_CONFIG_H
00027 #  include <config.h>
00028 #endif
00029 
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <unistd.h>
00033 #include <string.h>
00034 
00036 #define IPCPLUS_MAX_MESSAGE_SIZE  512
00037 
00038 #define IPCPLUS_MIN_MESSAGE_PRIOR 100
00039 
00045 namespace IPC
00046 {
00052     class Shm
00053     {
00054     protected:
00058         int mid;
00059     public:
00061         void *pMem;
00062         
00076         Shm (const unsigned int key, const size_t size);
00083         virtual ~Shm ();
00089         virtual bool destroy ();
00090     };
00091     
00095     class SemSet
00096     {
00097     private:
00101         int sid;
00105         int numSemaphores;
00106     public:
00118         SemSet (const unsigned int key, const int num = 5, const bool createIfNotExist = true);
00122         virtual ~SemSet ()
00123         {
00124         };
00129         int numSem (void) {
00130             return numSemaphores;
00131         };
00137         virtual bool destroy ();
00144         bool semOp (const int semIdx, const int semOperation);
00145     };
00146     
00152     class Mutex
00153     {
00154     private:
00156         SemSet *pSet;
00158         int semIdx;
00159     public:
00166         Mutex (SemSet *pSemSet, const int idx)
00167             : pSet (pSemSet)
00168             , semIdx (idx)
00169         {
00170         };
00172         virtual ~Mutex ()
00173         {
00174         };
00182         bool Wait ()
00183         {
00184             return pSet->semOp (semIdx, -1);
00185         };
00192         bool Signal ()
00193         {
00194             return pSet->semOp (semIdx, 1);
00195         };
00196     };
00197     
00205     class CritSec
00206     {
00207     private:
00209         Mutex *pMut;
00210     public:
00212         CritSec (Mutex *pMutex)
00213             : pMut (pMutex)
00214         {
00215             if (!pMut->Wait ()) {
00216                 // we can safely assume this is a fatal error.
00217                 abort ();
00218             }
00219         };
00221         virtual ~CritSec ()
00222         {
00223             if (!pMut->Signal ()) {
00224                 // This might not be a FATAL error but it certainly isn't expected in a well-written program!
00225                 fprintf (stderr, "Program error: Failed to leave critical section in an orderly manner.\n");
00226             }
00227         };
00228     };
00229     
00233     class Msg
00234     {
00235     private:
00239         int qid;
00240     public:
00244         struct {
00245             long mtype;
00246             char mdata [IPCPLUS_MAX_MESSAGE_SIZE];
00247         } msgbuf;
00251         unsigned int mSize;
00255         Msg ();
00265         Msg (const unsigned int key, const bool createIfNotExist = true);
00269         virtual ~Msg ()
00270         {
00271         };
00278         bool Snd ();
00289         bool Snd (const void *data, const size_t size, const int mType = 1);
00299         bool Snd (const char *string, const int mType = 1)
00300         {
00301             return Snd (string, strlen (string) + 1, mType);
00302         };
00309         bool Rcv (const int mType = 0, const int mFlag = 0);
00321         bool RcvHigh ()
00322         {
00323             return Rcv (-IPCPLUS_MIN_MESSAGE_PRIOR);
00324         };
00333         bool RcvType (const int mType)
00334         {
00335             return Rcv (mType);
00336         };
00342         virtual bool destroy ();
00348         unsigned int numMsg ();
00349     };
00350 
00357     class TwoWayMsg
00358     {
00359     protected:
00361         Msg *req, *rep;
00362     public:
00368         TwoWayMsg (const unsigned int key0)
00369         {
00370             req = new Msg (key0);
00371             rep = new Msg (key0 + 1);
00372         };
00378         virtual ~TwoWayMsg ()
00379         {
00380             delete req;
00381             delete rep;
00382         };
00389         virtual bool destroy ()
00390         {
00391             bool r1 = false;
00392             if (req) {
00393                 r1 = req->destroy ();
00394             }
00395             bool r2 = false;
00396             if (rep) {
00397                 r2 = rep->destroy ();
00398             }
00399             // assure nobody will use these anymore
00400             delete req;
00401             req = NULL;
00402             delete rep;
00403             rep = NULL;
00404             return r1 && r2;
00405         };
00415         virtual bool xmitReq (const void *data, const size_t size, const int mType = 1)
00416         {
00417             return req->Snd (data, size, mType);
00418         };
00428         virtual bool xmitRep (const void *data, const size_t size, const int mType = 1)
00429         {
00430             return rep->Snd (data, size, mType);
00431         };
00440         virtual bool recvReq (void *mData, size_t &mSize, const int mType = 1)
00441         {
00442             if (req->Rcv (mType)) {
00443                 memcpy (mData, req->msgbuf.mdata, mSize = req->mSize);
00444                 return true;
00445             }
00446             return false;
00447         };
00456         virtual bool recvRep (void *mData, size_t &mSize, const int mType = 1)
00457         {
00458             if (rep->Rcv (mType)) {
00459                 memcpy (mData, rep->msgbuf.mdata, mSize = rep->mSize);
00460                 return true;
00461             }
00462             return false;
00463         };
00464     };
00465 
00469     class MsgServer : public TwoWayMsg
00470     {
00471     private:
00473         int nextClient;
00474     public:
00478         MsgServer (const unsigned int key0)
00479             : TwoWayMsg (key0)
00480             , nextClient (0x100)
00481         {
00482         };
00486         virtual ~MsgServer ()
00487         {
00488             destroy ();
00489         };
00498         virtual bool xmit (const void *data, const size_t size)
00499         {
00500             return xmitRep (data, size, req->msgbuf.mtype);
00501         };
00513         virtual bool recv (void *mData, size_t &mSize);
00514     };
00515     
00519     class MsgClient : public TwoWayMsg
00520     {
00521     private:
00527         int myAddress;
00528     public:
00532         MsgClient (const unsigned int key0)
00533             : TwoWayMsg (key0)
00534             , myAddress (0)
00535         {
00536         };
00540         virtual ~MsgClient ()
00541         {
00542         };
00551         virtual bool xmit (const void *data, const size_t size);
00559         virtual bool recv (void *mData, size_t &mSize)
00560         {
00561             if (!myAddress) {
00562                 return false;
00563             }
00564             return recvRep (mData, mSize, myAddress);
00565         };
00566     };
00567 } // namespace IPC
00568 
00569 #endif  /*H_include_IPC*/
00570 
00571 

Generated on Wed May 15 09:33:33 2002 for IPCPlus by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001