00001
00002 #ifdef PLATFORM_APERIOS
00003 # include <OPENR/RCRegion.h>
00004 #else
00005 # ifndef INCLUDED_RCRegion_h_
00006 # define INCLUDED_RCRegion_h_
00007
00008 #include "Shared/ReferenceCounter.h"
00009 #include "MutexLock.h"
00010 #include "ProcessID.h"
00011 #include "Shared/plist.h"
00012 #include <sys/types.h>
00013 #include <map>
00014 #include <exception>
00015
00016
00017
00018
00019 #ifndef POSIX_SHM
00020 # define POSIX_SHM 1
00021 #endif
00022 #ifndef SYSV_SHM
00023 # define SYSV_SHM 2
00024 #endif
00025 #ifndef TEKKOTSU_SHM_STYLE
00026 # define TEKKOTSU_SHM_STYLE POSIX_SHM
00027 #endif
00028
00029 #if TEKKOTSU_SHM_STYLE!=SYSV_SHM && TEKKOTSU_SHM_STYLE!=POSIX_SHM
00030 # error Unknown TEKKOTSU_SHM_STYLE setting
00031 #endif
00032
00033
00034
00035 class RCRegion {
00036 public:
00037 #if TEKKOTSU_SHM_STYLE==SYSV_SHM
00038
00039 struct Identifier {
00040 Identifier() : key(), shmid(), size(0) {}
00041 key_t key;
00042 int shmid;
00043 size_t size;
00044 };
00045
00046 explicit RCRegion(size_t sz)
00047 : id(), base(NULL), references(NULL), lock(NULL)
00048 { init(sz,nextKey,true); }
00049
00050
00051 RCRegion(const std::string&, size_t sz)
00052 : id(), base(NULL), references(NULL), lock(NULL)
00053 { init(sz,nextKey,true); }
00054 #elif TEKKOTSU_SHM_STYLE==POSIX_SHM
00055
00056 static const unsigned int MAX_NAME_LEN=64;
00057 # ifndef USE_UNBACKED_SHM
00058 static plist::Primitive<std::string> shmRoot;
00059 # endif
00060 static plist::Primitive<bool> useUniqueMemoryRegions;
00061 static pid_t rootPID;
00062 struct Identifier {
00063 Identifier() : size(0) {}
00064 char key[MAX_NAME_LEN];
00065 size_t size;
00066 };
00067
00068 explicit RCRegion(size_t sz)
00069 : id(), base(NULL), references(NULL), lock(NULL)
00070 {
00071 char name[RCRegion::MAX_NAME_LEN];
00072 static unsigned int sn=0;
00073 snprintf(name,RCRegion::MAX_NAME_LEN,"Rgn.%d.%d",ProcessID::getID(),++sn);
00074 name[RCRegion::MAX_NAME_LEN-1]='\0';
00075 init(sz,name,true);
00076 }
00077
00078 RCRegion(const std::string& name, size_t sz)
00079 : id(), base(NULL), references(NULL), lock(NULL)
00080 { init(sz,name,true); }
00081 #endif
00082
00083 static RCRegion * attach(const Identifier& rid);
00084
00085 char * Base() const { return base; }
00086 size_t Size() const { return id.size; }
00087 static void setNextKey(key_t k) { nextKey=k; }
00088 const Identifier& ID() const { return id; }
00089
00090 int NumberOfReference() const { return references[ProcessID::NumProcesses]; }
00091 int NumberOfLocalReference() const { return references[ProcessID::getID()]; }
00092 void AddReference();
00093 void RemoveReference();
00094 void AddSharedReference();
00095 void RemoveSharedReference();
00096
00097 static void aboutToFork(ProcessID::ProcessID_t newID);
00098 static void faultShutdown();
00099 static unsigned int NumberOfAttach() { return attachedRegions.size(); }
00100
00101
00102 enum ConflictResolutionStrategy {
00103 RENAME,
00104 REPLACE,
00105 EXIT
00106 };
00107
00108 static void setConflictResolution(ConflictResolutionStrategy crs) { conflictStrategy=crs; }
00109 static ConflictResolutionStrategy getConflictResolution() { return conflictStrategy; }
00110
00111 protected:
00112 RCRegion(const Identifier& rid)
00113 : id(), base(NULL), references(NULL), lock(NULL)
00114 { init(rid.size,rid.key,false); }
00115
00116 ~RCRegion();
00117
00118 static const unsigned int align=sizeof(unsigned int);
00119 static const unsigned int extra=sizeof(unsigned int)*(ProcessID::NumProcesses+1)
00120 +sizeof(MutexLock<ProcessID::NumProcesses>);
00121 static unsigned int calcRealSize(unsigned int size);
00122
00123 #if TEKKOTSU_SHM_STYLE==SYSV_SHM
00124 void init(size_t sz, key_t sug_key, bool create);
00125 #elif TEKKOTSU_SHM_STYLE==POSIX_SHM
00126 std::string getQualifiedName() const { return getQualifiedName(id.key); }
00127 static std::string getQualifiedName(const std::string& key);
00128 int openRegion(int mode) const;
00129 bool unlinkRegion() const;
00130 void init(size_t sz, const std::string& name, bool create);
00131 #endif
00132
00133 static ConflictResolutionStrategy conflictStrategy;
00134 static bool isFaultShutdown;
00135
00136 static key_t nextKey;
00137 #if TEKKOTSU_SHM_STYLE==SYSV_SHM
00138 typedef std::map<key_t,RCRegion*> attachedRegions_t;
00139 #elif TEKKOTSU_SHM_STYLE==POSIX_SHM
00140 typedef std::map<std::string,RCRegion*> attachedRegions_t;
00141 #endif
00142 static attachedRegions_t attachedRegions;
00143
00144 Identifier id;
00145 char * base;
00146 unsigned int * references;
00147 MutexLock<ProcessID::NumProcesses> * lock;
00148
00149 private:
00150 RCRegion(const RCRegion& r);
00151 RCRegion& operator=(const RCRegion& r);
00152 };
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 # endif
00166 #endif