Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

RCRegion.h

Go to the documentation of this file.
00001 //-*-c++-*-
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 //do you want to use the SysV shared memory call interface
00017 //or the POSIX shared memory interface?  They have different
00018 //strengths/weaknesses on different platforms... :-/
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 //! provides compatability with the OPEN-R type of the same name
00035 class RCRegion {
00036 public:
00037 #if TEKKOTSU_SHM_STYLE==SYSV_SHM
00038   //! contains all information needed to attach this region from a different process
00039   struct Identifier {
00040     Identifier() : key(), shmid(), size(0) {}
00041     key_t key;
00042     int shmid;
00043     size_t size;
00044   };
00045   //! constructor (OPEN-R compatability)
00046   explicit RCRegion(size_t sz)
00047     : id(), base(NULL), references(NULL), lock(NULL)
00048   { init(sz,nextKey,true); }
00049   //! constructor, name isn't used for sysv
00050   /*! could hash the name to generate key...? */
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   //! maximum guaranteed length for users' region names (might have a little leeway depending on process ID prefix or tmp path prefix)
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; //!< this is the pid of the original process, used for unique names of memory regions; pid_t is from sys/types.h
00062   struct Identifier {
00063     Identifier() : size(0) {}
00064     char key[MAX_NAME_LEN];
00065     size_t size;
00066   };
00067   //! constructor (OPEN-R compatability, name is autogenerated)
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   //! constructor, specify your own name for better debugging accountability (not OPEN-R compatable)
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   //! Different methods of handling regions with conflicting keys
00102   enum ConflictResolutionStrategy {
00103     RENAME,  //!< try another key until we find one that works (better for SYSV, maybe not so smart for POSIX)
00104     REPLACE, //!< delete the other region and try again (better for POSIX, maybe not so smart for SYSV)
00105     EXIT //!< go home and cry about it
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); //!< don't call
00151   RCRegion& operator=(const RCRegion& r); //!< don't call
00152 };
00153 
00154 /*! @file
00155  * @brief Describes RCRegion, which provides compatability with the OPEN-R type of the same name
00156  * @author ejt (Creator)
00157  *
00158  * $Author: ejt $
00159  * $Name: tekkotsu-2_4_1 $
00160  * $Revision: 1.2 $
00161  * $State: Exp $
00162  * $Date: 2005/06/01 05:47:46 $
00163  */
00164 
00165 #  endif
00166 #endif

Tekkotsu v2.4.1
Generated Tue Aug 16 16:32:48 2005 by Doxygen 1.4.4