00001 #ifndef SHAREDMEM_TRANSPORT_PUBLISHER_H 00002 #define SHAREDMEM_TRANSPORT_PUBLISHER_H 00003 00004 00005 #include <std_msgs/Header.h> 00006 #include "message_transport/simple_publisher_plugin.h" 00007 #include "sharedmem_transport/SharedMemHeader.h" 00008 #include "sharedmem_transport/SharedMemoryBlock.h" 00009 00010 namespace sharedmem_transport { 00011 00012 class SharedmemPublisherImpl 00013 { 00014 public: 00015 SharedmemPublisherImpl(); 00016 virtual ~SharedmemPublisherImpl(); 00017 00018 uint32_t initialise(const std::string & topic); 00019 00020 void setNodeHandle(ros::NodeHandle & nh) { 00021 nh_ = nh; 00022 } 00023 00024 00025 template <class M> 00026 void publish_msg(const M& message) { 00027 uint32_t serlen = ros::serialization::serializationLength(message); 00028 00029 if (!shm_handle_.is_valid()) { 00030 ROS_DEBUG("Ignoring publish request on an invalid handle"); 00031 return; 00032 } 00033 blockmgr_->reallocateBlock(*segment_,shm_handle_,serlen); 00034 if (shm_handle_.is_valid()) { // check again, in case reallocate failed 00035 blockmgr_->serialize(*segment_,shm_handle_,message); 00036 } 00037 } 00038 protected: 00039 boost::interprocess::managed_shared_memory *segment_ ; 00040 SharedMemoryBlock *blockmgr_; 00041 bool clientRegistered; 00042 00043 // This will be modified after the first image is received, so we 00044 // mark them mutable and publish stays "const" 00045 shm_handle shm_handle_; 00046 ros::NodeHandle nh_; 00047 00048 }; 00049 00050 template <class Base> 00051 class SharedmemPublisher : 00052 public message_transport::SimplePublisherPlugin<Base,sharedmem_transport::SharedMemHeader> 00053 { 00054 public: 00055 SharedmemPublisher() : 00056 message_transport::SimplePublisherPlugin<Base,sharedmem_transport::SharedMemHeader>(true), // force latch 00057 first_run_(true) {} 00058 virtual ~SharedmemPublisher() {} 00059 00060 virtual std::string getTransportName() const 00061 { 00062 return "sharedmem"; 00063 } 00064 00065 protected: 00066 virtual void postAdvertiseInit() { 00067 impl.setNodeHandle(this->getNodeHandle()); 00068 } 00069 00070 virtual void publish(const Base& message, 00071 const typename message_transport::SimplePublisherPlugin<Base,sharedmem_transport::SharedMemHeader>::PublishFn& publish_fn) const { 00072 if (first_run_) { 00073 ROS_INFO("First publish run"); 00074 SharedMemHeader header; 00075 header.handle = impl.initialise(this->getTopic()); 00076 ROS_INFO("Publishing latched header"); 00077 publish_fn(header); 00078 first_run_ = false; 00079 } 00080 ROS_DEBUG("Publishing shm message"); 00081 impl.publish_msg(message); 00082 } 00083 00084 mutable SharedmemPublisherImpl impl; 00085 mutable bool first_run_; 00086 00087 }; 00088 00089 } //namespace sharedmem_transport 00090 00091 00092 #endif // SHAREDMEM_TRANSPORT_PUBLISHER_H