int MulticastClientTransport::send( I_ClientTransportCallback &clientStub, const std::vector<ByteBuffer> &data, unsigned int timeoutMs) { // TODO: in some cases, may need to make a full copy of data for // each individual sub-transport, as they might transform the data. bringInNewTransports(); Lock lock(mClientTransportsMutex); // TODO: hardcoded timeoutMs = 1000; bool needToRemove = false; ClientTransportList::iterator iter; for ( iter = mClientTransports.begin(); iter != mClientTransports.end(); ++iter) { try { if ((**iter)->isInProcess()) { ClientStub & stub = static_cast<ClientStub &>(clientStub); (**iter)->doInProcessCall(stub); } else { // We used to check *iter->isConnected() here, and if so not // try the send at all. Appear to have been synchronization // issues when doing that though. // Sending synchronously, so no use for the callback DummyCallback dummyCallback; (**iter)->send(dummyCallback, data, timeoutMs); } } catch(const Exception &e) { RCF_LOG_1()(e) << "Error publishing to subscriber."; needToRemove = true; iter->reset(); } } if (needToRemove) { mClientTransports.remove( ClientTransportAutoPtrPtr() ); } clientStub.onSendCompleted(); return 1; }
inline bool tryCreateRemoteObject( RCF::I_RcfClient &rcfClient, std::string objectName = "") { try { rcfClient.getClientStub().createRemoteObject(objectName); return true; } catch (const RCF::Exception &e) { RCF_LOG_1()(e); return false; } }
bool TokenFactory::requestToken(Token &token) { WriteLock writeLock(mMutex); RCF_UNUSED_VARIABLE(writeLock); if (mAvailableTokens.empty()) { RCF_LOG_1()(mAvailableTokens.size())(mTokenSpace.size()) << "TokenFactory - no more tokens available."; return false; } else { Token myToken = mAvailableTokens.back(); mAvailableTokens.pop_back(); token = myToken; return true; } }
void UdpServerTransport::open() { RCF_LOG_4()(mIpAddress.string()) << "UdpServerTransport - creating server socket."; int mPort = mIpAddress.getPort(); // create and bind a socket for receiving UDP messages if (mFd == -1 && mPort >= 0) { int ret = 0; int err = 0; mIpAddress.resolve(); mFd = mIpAddress.createSocket(SOCK_DGRAM, IPPROTO_UDP); // enable reception of broadcast messages int enable = 1; ret = setsockopt(mFd, SOL_SOCKET, SO_BROADCAST, (char *) &enable, sizeof(enable)); err = Platform::OS::BsdSockets::GetLastError(); if (ret) { RCF_LOG_1()(ret)(err) << "setsockopt() - failed to set SO_BROADCAST on listening udp socket."; } // Share the address binding, if appropriate. if (mEnableSharedAddressBinding) { enable = 1; // Set SO_REUSEADDR socket option. ret = setsockopt(mFd, SOL_SOCKET, SO_REUSEADDR, (char *) &enable, sizeof(enable)); err = Platform::OS::BsdSockets::GetLastError(); if (ret) { RCF_LOG_1()(ret)(err) << "setsockopt() - failed to set SO_REUSEADDR on listening udp multicast socket."; } // On OS X and BSD variants, need to set SO_REUSEPORT as well. #if (defined(__MACH__) && defined(__APPLE__)) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) ret = setsockopt(mFd, SOL_SOCKET, SO_REUSEPORT, (char *) &enable, sizeof(enable)); err = Platform::OS::BsdSockets::GetLastError(); if (ret) { RCF_LOG_1()(ret)(err) << "setsockopt() - failed to set SO_REUSEPORT on listening udp multicast socket."; } #endif } sockaddr * pServerAddr = NULL; Platform::OS::BsdSockets::socklen_t serverAddrSize = 0; mIpAddress.getSockAddr(pServerAddr, serverAddrSize); // bind the socket ret = ::bind(mFd, pServerAddr, serverAddrSize); if (ret < 0) { err = Platform::OS::BsdSockets::GetLastError(); Exception e(_RcfError_Socket("bind()"), err, RcfSubsystem_Os); RCF_THROW(e)(mFd)(mIpAddress.string())(ret); } RCF_ASSERT_NEQ( mFd , -1 ); if (!mMulticastIpAddress.empty()) { // set socket option for receiving multicast messages mMulticastIpAddress.resolve(); // TODO: implement for IPv6. RCF_ASSERT( mIpAddress.getType() == IpAddress::V4 && mMulticastIpAddress.getType() == IpAddress::V4); std::string ip = mMulticastIpAddress.getIp(); ip_mreq imr; imr.imr_multiaddr.s_addr = inet_addr(ip.c_str()); imr.imr_interface.s_addr = INADDR_ANY; int ret = setsockopt(mFd,IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*) &imr, sizeof(imr)); int err = Platform::OS::BsdSockets::GetLastError(); RCF_VERIFY( ret == 0, Exception( _RcfError_Socket("setsockopt() with IPPROTO_IP/IP_ADD_MEMBERSHIP"), err, RcfSubsystem_Os)) (mMulticastIpAddress.string())(mIpAddress.string()); // TODO: enable source-filtered multicast messages //ip_mreq_source imr; //imr.imr_multiaddr.s_addr = inet_addr("232.5.6.7"); //imr.imr_sourceaddr.s_addr = INADDR_ANY;//inet_addr("10.1.1.2"); //imr.imr_interface.s_addr = INADDR_ANY; //int ret = setsockopt(mFd,IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, (const char*) &imr, sizeof(imr)); //int err = Platform::OS::BsdSockets::GetLastError(); } // set the socket to nonblocking mode Platform::OS::BsdSockets::setblocking(mFd, false); // retrieve the port number, if it's generated by the system if (mPort == 0) { IpAddress ip(mFd, mIpAddress.getType()); mPort = ip.getPort(); mIpAddress.setPort(mPort); } RCF_LOG_2() << "UdpServerTransport - listening on port " << mPort << "."; } }