SharedObject.h
Go to the documentation of this file.00001
00002 #ifndef INCLUDED_SharedObject_h
00003 #define INCLUDED_SharedObject_h
00004
00005 #include "RCRegion.h"
00006 #include <stdexcept>
00007 #include <typeinfo>
00008
00009
00010
00011 class SharedObjectBase {
00012 public:
00013
00014 struct NoInit {};
00015
00016 void* data() const { return rcr->Base(); }
00017 RCRegion * getRegion() const { return rcr; }
00018
00019 virtual ~SharedObjectBase() {}
00020
00021 #ifndef PLATFORM_APERIOS
00022
00023 static unsigned int getNextKey() { return serialNumber+1; }
00024 #endif
00025
00026
00027 SharedObjectBase& operator=(const SharedObjectBase& sob) {
00028 if(rcr==sob.rcr)
00029 return *this;
00030 removeRef();
00031 rcr=sob.rcr;
00032 if(rcr!=NULL)
00033 rcr->AddReference();
00034 return *this;
00035 }
00036
00037 protected:
00038
00039 SharedObjectBase() : rcr(NULL) {}
00040
00041 SharedObjectBase(const SharedObjectBase& sob) : rcr(sob.rcr) {
00042 if(rcr!=NULL)
00043 rcr->AddReference();
00044 }
00045
00046
00047 virtual void removeRef()=0;
00048
00049 RCRegion * rcr;
00050
00051 #ifndef PLATFORM_APERIOS
00052 static unsigned int serialNumber;
00053 #endif
00054 };
00055
00056
00057
00058
00059 template<class MC>
00060 class SharedObject : public SharedObjectBase {
00061 public:
00062
00063
00064
00065
00066
00067 SharedObject() : SharedObjectBase() {
00068 rcr=createRCRegion();
00069 new (rcr->Base()) MC;
00070 }
00071
00072 template<class T1> explicit SharedObject(const T1& t1) : SharedObjectBase() {
00073 rcr=createRCRegion();
00074 new (rcr->Base()) MC(t1);
00075 }
00076
00077 template<class T1, class T2> SharedObject(const T1& t1, const T2& t2) : SharedObjectBase(){
00078 rcr=createRCRegion();
00079 new (rcr->Base()) MC(t1,t2);
00080 }
00081
00082 template<class T1, class T2, class T3> SharedObject(const T1& t1, const T2& t2, const T3& t3) : SharedObjectBase(){
00083 rcr=createRCRegion();
00084 new (rcr->Base()) MC(t1,t2,t3);
00085 }
00086
00087 template<class T1, class T2, class T3, class T4> SharedObject(const T1& t1, const T2& t2, const T3& t3, const T4& t4) : SharedObjectBase(){
00088 rcr=createRCRegion();
00089 new (rcr->Base()) MC(t1,t2,t3,t4);
00090 }
00091
00092 template<class T1, class T2, class T3, class T4, class T5> SharedObject(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) : SharedObjectBase(){
00093 rcr=createRCRegion();
00094 new (rcr->Base()) MC(t1,t2,t3,t4,t5);
00095 }
00096
00097
00098
00099 SharedObject(const SharedObjectBase::NoInit&) : SharedObjectBase() {}
00100
00101
00102 SharedObject(const SharedObject& sh) : SharedObjectBase(sh) {}
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 explicit SharedObject(RCRegion * r) : SharedObjectBase() {
00114 rcr=r;
00115 if(rcr->Size()!=sizeof(MC)) {
00116 #ifdef PLATFORM_APERIOS
00117 std::cerr << "ERROR: SharedObject(RCRegion* r) region size ("<<rcr->Size()<<") does not match size of SharedObject type ("<<sizeof(MC)<<")" << std::endl;
00118 #else
00119 std::cerr << "ERROR: SharedObject(RCRegion* r) region "<<rcr->ID().key<<" size ("<<rcr->Size()<<") does not match size of SharedObject type ("<<sizeof(MC)<<")" << std::endl;
00120 #endif
00121 throw std::invalid_argument("SharedObject(RCRegion* r): region size does not match sizeof(type)");
00122 }
00123 }
00124
00125
00126 virtual ~SharedObject() { removeRef(); }
00127
00128 MC* operator->() const { return dataCasted(); }
00129 MC& operator*() const { return *dataCasted(); }
00130 MC& operator[](int i) const { return dataCasted()[i]; }
00131
00132 protected:
00133 MC* dataCasted() const { return static_cast<MC*>(data()); }
00134
00135
00136 virtual void removeRef() {
00137 if(rcr!=NULL) {
00138
00139 if(rcr->NumberOfReference()>0) {
00140 if(rcr->NumberOfReference()==1)
00141 dataCasted()->~MC();
00142 rcr->RemoveReference();
00143 } else
00144 std::cerr << "WARNING: SharedObjectBase destructed without reference" << std::endl;
00145 rcr=NULL;
00146 }
00147 }
00148
00149
00150 static RCRegion * createRCRegion() {
00151 #ifdef PLATFORM_APERIOS
00152 RCRegion * r = new RCRegion(calcsize());
00153 #else
00154 char name[RCRegion::MAX_NAME_LEN];
00155 unsigned int suffixlen=snprintf(name,RCRegion::MAX_NAME_LEN,".%d.%d",ProcessID::getID(),++serialNumber);
00156 if(suffixlen>RCRegion::MAX_NAME_LEN)
00157 suffixlen=RCRegion::MAX_NAME_LEN;
00158 snprintf(name,RCRegion::MAX_NAME_LEN,"Sh.%.*s.%d.%d",RCRegion::MAX_NAME_LEN-suffixlen-3,typeid(MC).name(),ProcessID::getID(),++serialNumber);
00159 name[RCRegion::MAX_NAME_LEN-1]='\0';
00160 RCRegion * r = new RCRegion(name,calcsize());
00161 #endif
00162
00163
00164
00165
00166
00167 return r;
00168 }
00169
00170
00171
00172
00173
00174 static unsigned int calcsize() {
00175 #ifndef PLATFORM_APERIOS
00176 return sizeof(MC);
00177 #else
00178 size_t size = sizeof(MC);
00179 sError error;
00180 size_t page_size;
00181 error = GetPageSize(&page_size);
00182 if (error != sSUCCESS) {
00183 cout << "error: " << error << " getting page size in SharedMem" << endl;
00184 page_size = 4096;
00185 }
00186
00187 int new_size,num_pages;
00188 num_pages = (size+page_size-1)/page_size;
00189 new_size = num_pages*page_size;
00190
00191
00192
00193
00194
00195
00196 return new_size;
00197 #endif //!PLATFORM_APERIOS
00198 }
00199 };
00200
00201
00202
00203
00204
00205
00206 #endif //INCLUDED_SharedObject_h