ShmemDataLink.cpp

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Distributed under the OpenDDS License.
00005  * See: http://www.opendds.org/license.html
00006  */
00007 
00008 #include "ShmemDataLink.h"
00009 #include "ShmemTransport.h"
00010 #include "ShmemInst.h"
00011 #include "ShmemSendStrategy.h"
00012 #include "ShmemReceiveStrategy.h"
00013 
00014 #include "ace/Log_Msg.h"
00015 
00016 #include <cstdlib>
00017 
00018 #ifndef __ACE_INLINE__
00019 # include "ShmemDataLink.inl"
00020 #endif  /* __ACE_INLINE__ */
00021 
00022 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
00023 
00024 namespace OpenDDS {
00025 namespace DCPS {
00026 
00027 ShmemDataLink::ShmemDataLink(ShmemTransport& transport)
00028   : DataLink(transport,
00029              0,     // priority
00030              false, // is_loopback,
00031              false) // is_active
00032   , config_(0)
00033   , send_strategy_(make_rch<ShmemSendStrategy>(this))
00034   , recv_strategy_(make_rch<ShmemReceiveStrategy>(this))
00035   , peer_alloc_(0)
00036 {
00037 }
00038 
00039 bool
00040 ShmemDataLink::open(const std::string& peer_address)
00041 {
00042   peer_address_ = peer_address;
00043   const ACE_TString name = ACE_TEXT_CHAR_TO_TCHAR(peer_address.c_str());
00044   ShmemAllocator::MEMORY_POOL_OPTIONS alloc_opts;
00045 
00046 #ifdef ACE_WIN32
00047   const bool use_opts = true;
00048   const ACE_TString name_under = name + ACE_TEXT('_');
00049   // Find max size of peer's pool so enough local address space is reserved.
00050   HANDLE fm = ACE_TEXT_CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READONLY,
00051     0, ACE_DEFAULT_PAGEFILE_POOL_CHUNK, name_under.c_str());
00052   void* view;
00053   if (fm == 0 || (view = MapViewOfFile(fm, FILE_MAP_READ, 0, 0, 0)) == 0) {
00054     stop_i();
00055     ACE_ERROR_RETURN((LM_ERROR,
00056                       ACE_TEXT("(%P|%t) ERROR: ShmemDataLink::open: ")
00057                       ACE_TEXT("peer's shared memory area not found (%C)\n"),
00058                       peer_address.c_str()),
00059                      false);
00060   }
00061   // location of max_size_ in ctrl block: a size_t after two void*s
00062   const size_t* pmax = (const size_t*)(((void**)view) + 2);
00063   alloc_opts.max_size_ = *pmax;
00064   UnmapViewOfFile(view);
00065   CloseHandle(fm);
00066 #else
00067   const bool use_opts = false;
00068 #endif
00069 
00070   peer_alloc_ = new ShmemAllocator(name.c_str(), 0 /*lock_name*/,
00071                                    use_opts ? &alloc_opts : 0);
00072 
00073   if (-1 == peer_alloc_->find("Semaphore")) {
00074     stop_i();
00075     ACE_ERROR_RETURN((LM_ERROR,
00076                       ACE_TEXT("(%P|%t) ERROR: ShmemDataLink::open: ")
00077                       ACE_TEXT("peer's shared memory area not found (%C)\n"),
00078                       peer_address.c_str()),
00079                      false);
00080   }
00081 
00082   if (start(static_rchandle_cast<TransportSendStrategy>(send_strategy_),
00083             static_rchandle_cast<TransportStrategy>(recv_strategy_))
00084       != 0) {
00085     stop_i();
00086     ACE_ERROR_RETURN((LM_ERROR,
00087                       ACE_TEXT("(%P|%t) ERROR: ")
00088                       ACE_TEXT("ShmemDataLink::open: start failed!\n")),
00089                      false);
00090   }
00091 
00092   VDBG_LVL((LM_INFO, "(%P|%t) ShmemDataLink link %@ open to peer %C\n",
00093             this, peer_address_.c_str()), 1);
00094 
00095   return true;
00096 }
00097 
00098 void
00099 ShmemDataLink::control_received(ReceivedDataSample& /*sample*/)
00100 {
00101 }
00102 
00103 void
00104 ShmemDataLink::stop_i()
00105 {
00106   if (peer_alloc_) {
00107     peer_alloc_->release(0 /*don't close*/);
00108   }
00109   delete peer_alloc_;
00110   peer_alloc_ = 0;
00111 }
00112 
00113 ShmemTransport&
00114 ShmemDataLink::impl() const
00115 {
00116   return static_cast<ShmemTransport&>(DataLink::impl());
00117 }
00118 
00119 ShmemAllocator*
00120 ShmemDataLink::local_allocator()
00121 {
00122   return impl().alloc();
00123 }
00124 
00125 std::string
00126 ShmemDataLink::local_address()
00127 {
00128   return impl().address();
00129 }
00130 
00131 void
00132 ShmemDataLink::signal_semaphore()
00133 {
00134   return impl().signal_semaphore();
00135 }
00136 
00137 pid_t
00138 ShmemDataLink::peer_pid()
00139 {
00140   return std::atoi(peer_address_.c_str() + peer_address_.find('-') + 1);
00141 }
00142 
00143 } // namespace DCPS
00144 } // namespace OpenDDS
00145 
00146 OPENDDS_END_VERSIONED_NAMESPACE_DECL
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1