00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00217 abort ();
00218 }
00219 };
00221 virtual ~CritSec ()
00222 {
00223 if (!pMut->Signal ()) {
00224
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
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 }
00568
00569 #endif
00570
00571