Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

RegionRegistry.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_RegionRegistry_h_
00003 #define INCLUDED_RegionRegistry_h_
00004 
00005 #ifdef PLATFORM_APERIOS
00006 #  warning RegionRegistry is not Aperios compatable
00007 #else
00008 
00009 #include "ListMemBuf.h"
00010 #include "RCRegion.h"
00011 #include "LockScope.h"
00012 #include "ProcessID.h"
00013 
00014 //! Keeps track of currently available shared memory regions
00015 template<unsigned int MAX_REGIONS, unsigned int NAME_LEN=0>
00016 class RegionRegistry {
00017 protected:
00018   mutable MutexLock<ProcessID::NumProcesses> lock;
00019   typedef LockScope<ProcessID::NumProcesses> AutoLock;
00020   
00021   //! Holds information regarding a shared memory region available for listening
00022   struct entry {
00023     //! constructor
00024     entry() : id() { name[0]='\0'; }
00025     entry(const char n[], RCRegion* r) : id(r->ID()) {
00026       strncpy(name,n,NAME_LEN);
00027       name[NAME_LEN]='\0';
00028     }
00029     char name[NAME_LEN+1]; //!< the name for the region
00030     RCRegion::Identifier id;
00031   };
00032   typedef ListMemBuf<entry,MAX_REGIONS> registry_t;
00033   registry_t avail;
00034 
00035 public:
00036   static const unsigned int CAPACITY=MAX_REGIONS;
00037   static const unsigned int REGION_NAME_LEN=NAME_LEN;
00038   typedef typename registry_t::index_t index_t;
00039 
00040   RegionRegistry() : lock(), avail() {}
00041   
00042   ~RegionRegistry() {
00043     AutoLock autolock(lock,ProcessID::getID());
00044     avail.clear();
00045   }
00046   
00047   index_t findRegion(const std::string& name) const {
00048     AutoLock autolock(lock,ProcessID::getID());
00049     if(name.size()>NAME_LEN)
00050       std::cerr << "WARNING: RegionRegistry::attach("<<name<<") is too long, max is " << NAME_LEN << std::endl;
00051     for(index_t it=begin(); it!=end(); it=next(it))
00052       if(name==avail[it].name)
00053         return it;
00054     return avail.end();
00055   }
00056 
00057   index_t registerRegion(const std::string& name, const RCRegion * region) {
00058     AutoLock autolock(lock,ProcessID::getID());
00059     index_t it=findRegion(name);
00060     if(it!=end()) { //found, already registered
00061       if(avail[it].regions[ProcessID::getID()]==region)
00062         return it; //same one, just return it
00063       return end(); // conflict, return invalid
00064     }
00065     //not found, make a new one
00066     return avail.push_back(entry(name.c_str(),region));
00067   }
00068   
00069   RCRegion * registerRegion(const std::string& name, size_t size) {
00070     AutoLock autolock(lock,ProcessID::getID());
00071     index_t it=findRegion(name);
00072     if(it!=end()) {
00073       //found, already registered
00074       return RCRegion::attach(avail[it].id);
00075     } else {
00076       //not found:
00077       RCRegion * region = new RCRegion(name,size);
00078       avail.push_back(entry(name.c_str(),region));
00079       return region;
00080     }
00081   }
00082   
00083   RCRegion * operator[](index_t it) const {
00084     AutoLock autolock(lock,ProcessID::getID());
00085     if(it==end())
00086       return NULL;
00087     return RCRegion::attach(avail[it].id);
00088   }
00089   
00090   void erase(index_t it) {
00091     AutoLock autolock(lock,ProcessID::getID());
00092     avail.erase(it);
00093   }
00094   
00095   index_t begin() const { return avail.begin(); }
00096   index_t next(index_t it) const { return avail.next(it); }
00097   index_t end() const { return avail.end(); }
00098 };
00099 
00100 /*! @file
00101  * @brief 
00102  * @author ejt (Creator)
00103  *
00104  * $Author: ejt $
00105  * $Name: tekkotsu-2_4_1 $
00106  * $Revision: 1.2 $
00107  * $State: Exp $
00108  * $Date: 2005/06/01 05:47:46 $
00109  */
00110 
00111 #endif //Aperios check
00112 
00113 #endif //INCLUDED
00114 

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