shm_object.hpp
Go to the documentation of this file.
00001 #ifndef __SHM_OBJECT_HPP__
00002 #define __SHM_OBJECT_HPP__
00003 
00004 #include <boost/interprocess/managed_shared_memory.hpp>
00005 #include <boost/atomic/atomic.hpp>
00006 
00007 namespace shm_transport
00008 {
00009 
00010 // some typedef for short
00011 typedef boost::atomic< uint32_t > atomic_uint32_t;
00012 typedef boost::interprocess::managed_shared_memory mng_shm;
00013 typedef boost::shared_ptr< boost::interprocess::managed_shared_memory > mng_shm_ptr;
00014 typedef boost::interprocess::interprocess_mutex ipc_mutex;
00015 
00016 class MsgListHead
00017 {
00018 public:
00019   MsgListHead() : next(0), prev(0) { }
00020   ~MsgListHead() { }
00021 
00022   void addLast(MsgListHead * lc, const mng_shm_ptr & pshm) {
00023     long hc = pshm->get_handle_from_address(lc);
00024     long hn = pshm->get_handle_from_address(this), hp = this->prev;
00025     MsgListHead * ln = this, * lp = (MsgListHead *)pshm->get_address_from_handle(hp);
00026     lc->next = hn;
00027     lc->prev = hp;
00028     lp->next = hc;
00029     ln->prev = hc;
00030   }
00031 
00032   void remove(MsgListHead * lc, const mng_shm_ptr & pshm) {
00033     long hc = pshm->get_handle_from_address(lc);
00034     long hn = lc->next, hp = lc->prev;
00035     MsgListHead * ln = (MsgListHead *)pshm->get_address_from_handle(hn);
00036     MsgListHead * lp = (MsgListHead *)pshm->get_address_from_handle(hp);
00037     lp->next = hn;
00038     ln->prev = hp;
00039   }
00040 
00041   void releaseFirst(const mng_shm_ptr & pshm) {
00042     long hc = next;
00043     MsgListHead * lc = (MsgListHead *)pshm->get_address_from_handle(hc);
00044     if (lc == this)
00045       return;
00046     long hn = lc->next, hp = lc->prev;
00047     MsgListHead * ln = (MsgListHead *)pshm->get_address_from_handle(hn), * lp = this;
00048     lp->next = hn;
00049     ln->prev = hp;
00050     pshm->deallocate(lc);
00051   }
00052 
00053   long getFirstHandle() {
00054     return next;
00055   }
00056 
00057 public:
00058   long next;
00059   long prev;
00060 };
00061 
00062 class ShmObject
00063 {
00064 public:
00065   ShmObject(mng_shm * pshm, std::string name)
00066       : pshm_(pshm), name_(name) {
00067     pref_ = pshm_->find_or_construct< atomic_uint32_t >("ref")(0);
00068     plck_ = pshm_->find_or_construct< ipc_mutex >("lck")();
00069     pmsg_ = pshm_->find_or_construct< MsgListHead >("lst")();
00070 
00071     pref_->fetch_add(1, boost::memory_order_relaxed);
00072     if (pmsg_->next == 0) {
00073       long handle = pshm_->get_handle_from_address(pmsg_);
00074       pmsg_->next = handle;
00075       pmsg_->prev = handle;
00076     }
00077   }
00078 
00079   ~ShmObject() {
00080     if (pref_->fetch_sub(1, boost::memory_order_relaxed) == 1) {
00081       boost::interprocess::shared_memory_object::remove(name_.c_str());
00082       //printf("shm file <%s> removed\n", name_.c_str());
00083     }
00084   }
00085 
00086 public:
00087   // smart pointer of shm
00088   mng_shm_ptr pshm_;
00089   // name of shm
00090   std::string name_;
00091   // in shm, reference count (pub # + sub #)
00092   atomic_uint32_t * pref_;
00093   // in shm, connection lock
00094   ipc_mutex * plck_;
00095   // in shm, head node of double-linked message list
00096   MsgListHead * pmsg_;
00097 };
00098 typedef boost::shared_ptr< ShmObject > ShmObjectPtr;
00099 
00100 // message object stored in *shared memory*
00101 class ShmMessage
00102 {
00103 public:
00104   // called by publisher
00105   void construct(const ShmObjectPtr & so) {
00106     // insert into message list
00107     so->pmsg_->addLast(&lst, so->pshm_);
00108     // set reference count
00109     ref = 0;
00110   }
00111 
00112   // called by subscriber
00113 
00114   void take() {
00115     ref.fetch_add(1, boost::memory_order_relaxed);
00116   }
00117 
00118   void release() {
00119     // just decrease the ref counter.
00120     // do not deallocate here, publisher will do that
00121     ref.fetch_sub(1, boost::memory_order_relaxed);
00122   }
00123 
00124 public:
00125   MsgListHead     lst;
00126   atomic_uint32_t ref;
00127   uint32_t        len;
00128   uint8_t         data[0];
00129 };
00130 
00131 } // namespace shm_transport
00132 
00133 #endif // __SHM_PUBLISHER_HPP__
00134 


shm_transport
Author(s): Jrdevil-Wang , Wende Tan
autogenerated on Thu Jun 6 2019 18:47:43