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