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

SemaphoreSet.h

Go to the documentation of this file.
00001 #ifndef __SEMAPHORESET_H
00002 #define __SEMAPHOERSET_H
00003 
00004 #include <string.h>
00005 #include <sys/types.h>
00006 #include <sys/ipc.h>
00007 #include <sys/sem.h>
00008 #include "ExceptionBase.h"
00009 
00010 namespace SemSet
00011 {
00012     #define ALL_SEMS 0
00013     
00014     typedef union semun
00015     {
00016         int val;
00017         struct smid_ds *buf;
00018         ushort *array;
00019     } arg;
00020 
00021 
00028     class SemException : public ExceptionBase
00029     {
00030     public:
00034         SemException() : ExceptionBase() {};
00035     
00041         SemException(const char* mess) : ExceptionBase(mess) {};
00042     
00046         ~SemException() {};
00047     };
00048 
00049 
00056     class SemUnknownSetException : public ExceptionBase
00057     {
00058     public:
00062         SemUnknownSetException() : ExceptionBase() {};
00063     
00069         SemUnknownSetException(const char* mess) : ExceptionBase(mess) {};
00070     
00074         ~SemUnknownSetException() {};
00075     };
00076 
00077 
00084     class SemaphoreSet
00085     {
00086     public:
00090         enum SemSetRetVal { OK, FAIL };
00091     
00097         SemaphoreSet(int numOfSems)
00098         {
00099             semSetId = semget(IPC_PRIVATE, numOfSems, IPC_CREAT | 0666);
00100             if (semSetId == -1) 
00101             {
00102                 semSetId = FAIL;
00103                 return;
00104             }
00105 
00106             arg semVal;
00107             semVal.val = 1;
00108 
00109             for (int i = 0; i < numOfSems; i++)
00110             {
00111                 int tmpRet = semctl(semSetId, i, SETVAL, semVal);
00112                 if (tmpRet == -1)
00113                 {
00114                     semSetId = FAIL;
00115                     destroyAll();
00116                     return;
00117                 }
00118             }
00119         }
00120     
00126         SemaphoreSet(const SemaphoreSet &otherSet)
00127         {
00128             semSetId = otherSet.semSetId;
00129         }
00130     
00134         ~SemaphoreSet() throw(SemUnknownSetException)
00135         {
00136             if (semSetId > 0)
00137             {
00138                 try 
00139                 {
00140                     destroyAll();
00141                 }
00142                 catch (SemException &e)
00143                 {
00144                     throw SemUnknownSetException("SemaphoreSet::~SemaphoreSet : set was probably already destroyed by another process");
00145                 }
00146             }
00147         }
00148     
00156         SemSetRetVal lock(int semNum) throw(SemException)
00157         {
00158             struct sembuf op;
00159 
00160             if (semSetId <= 0)
00161                 throw SemException("Semaphore set in wrong condition");
00162 
00163             op.sem_num = semNum;
00164             op.sem_op = -1;
00165             op.sem_flg = SEM_UNDO;
00166 
00167             int tmpRet = semop(semSetId, &op, 1);
00168             if (tmpRet == -1)
00169                 return FAIL;
00170 
00171             return OK;
00172         }
00173     
00181         SemSetRetVal unlock(int semNum) throw(SemException)
00182         {
00183             struct sembuf op;
00184 
00185             if (semSetId <= 0)
00186                 throw SemException("Semaphore set in wrong condition");
00187 
00188             op.sem_num = semNum;
00189             op.sem_op = 1;
00190             op.sem_flg = SEM_UNDO;
00191 
00192             int tmpRet = semop(semSetId, &op, 1);
00193             if (tmpRet == -1)
00194                 return FAIL;
00195 
00196             return OK;
00197         }
00198     
00199     private:
00200         int semSetId;
00201     
00202         SemSetRetVal destroyAll()
00203         {
00204             arg semVal; 
00205 
00206             if (semSetId <= 0)
00207                 throw SemException("Semaphore set in wrong condition");
00208 
00209             int tmpRet = semctl(semSetId, ALL_SEMS, IPC_RMID, semVal);
00210             if (tmpRet == -1)
00211             {
00212                 semSetId = FAIL;
00213                 throw SemException("Couldn't destroy a semaphore set");
00214             }
00215             return OK;
00216         }
00217     };
00218 }
00219 
00220 #endif //__SEMAPHOERESET_H

Generated on Thu Jan 27 10:06:44 2005 for ShmAllocator by doxygen 1.3.6