00001 #ifndef __SSI_SHMAM__
00002 #define __SSI_SHMAM__
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <pthread.h>
00033
00034 #include "XrdSsi/XrdSsiAtomics.hh"
00035 #include "XrdSsi/XrdSsiShMat.hh"
00036
00037 class XrdSsiShMam : public XrdSsiShMat
00038 {
00039 public:
00040
00041 bool AddItem(void *newdata, void *olddata, const char *key,
00042 int hash, bool replace=false);
00043
00044 bool Attach(int tout, bool isrw=false);
00045
00046 bool Create(XrdSsiShMat::CRZParms &parms);
00047
00048 bool Export();
00049
00050 bool DelItem(void *data, const char *key, int hash);
00051
00052 void Detach();
00053
00054 bool Enumerate(void *&jar, char *&key, void *&val);
00055
00056 bool Enumerate(void *&jar);
00057
00058 bool GetItem(void *data, const char *key, int hash);
00059
00060 int Info(const char *vname, char *buff=0, int blen=0);
00061
00062 bool Resize(XrdSsiShMat::CRZParms &parms);
00063
00064 bool Sync();
00065 bool Sync(bool dosync, bool syncdo);
00066 bool Sync(int syncqsz);
00067
00068 XrdSsiShMam(XrdSsiShMat::NewParms &parms);
00069
00070 ~XrdSsiShMam() {Detach();
00071 pthread_mutex_destroy(&lkMutex);
00072 pthread_rwlock_destroy(&myMutex);
00073 }
00074
00075 enum LockType {ROLock= 0, RWLock = 1};
00076
00077 private:
00078 struct MemItem {int hash; Atomic(int) next;};
00079
00080 bool ExportIt(bool fLocked);
00081 int Find(MemItem *&theItem, MemItem *&prvItem, const char *key, int &hash);
00082 bool Flush();
00083 int HashVal(const char *key);
00084 bool Lock(bool doRW=false, bool nowait=false);
00085 MemItem *NewItem();
00086 bool ReMap(LockType iHave);
00087 void RetItem(MemItem *iP);
00088 void SetLocking(bool isrw);
00089 void SwapMap(XrdSsiShMam &newMap);
00090 void Snooze(int sec);
00091 void UnLock(bool isrw);
00092 void Updated(int mOff);
00093 void Updated(int mOff, int mLen);
00094
00095 class XLockHelper
00096 {
00097 public:
00098 inline bool FLock() {if (!(shmemP->Lock(lkType))) return false;
00099 doUnLock = true; return true;
00100 }
00101
00102 XLockHelper(XrdSsiShMam *shmemp, LockType lktype)
00103 : shmemP(shmemp), lkType(lktype), doUnLock(false)
00104 {if (lktype == RWLock)
00105 pthread_rwlock_wrlock(&(shmemP->myMutex));
00106 else pthread_rwlock_rdlock(&(shmemP->myMutex));
00107 }
00108 ~XLockHelper() {int rc = errno;
00109 if (lkType == RWLock && shmemP->syncOn
00110 && shmemP->syncQWR > shmemP->syncQSZ)
00111 shmemP-> Flush();
00112 if (doUnLock) shmemP->UnLock(lkType == RWLock);
00113 pthread_rwlock_unlock(&(shmemP->myMutex));
00114 errno = rc;
00115 }
00116 private:
00117 XrdSsiShMam *shmemP;
00118 LockType lkType;
00119 bool doUnLock;
00120 };
00121
00122 pthread_mutex_t lkMutex;
00123 pthread_rwlock_t myMutex;
00124
00125 char *shmTemp;
00126 long long shmSize;
00127 char *shmBase;
00128 Atomic(int)*shmIndex;
00129 int shmSlots;
00130 int shmItemSz;
00131 int shmInfoSz;
00132 int verNum;
00133 int keyPos;
00134 int maxKLen;
00135 int shmFD;
00136 int timeOut;
00137 int lkCount;
00138 int syncOpt;
00139 int syncQWR;
00140 int syncLast;
00141 int syncQSZ;
00142 int accMode;
00143 bool isRW;
00144 bool lockRO;
00145 bool lockRW;
00146 bool reUse;
00147 bool multW;
00148 bool useAtomic;
00149 bool syncBase;
00150 bool syncOn;
00151 };
00152 #endif