ReadWriteMutex::ReadWriteMutex(ReadWritePriority rwsp) : readerCount() { RCF_UNUSED_VARIABLE(rwsp); }
void UdpServerTransport::cycle(int timeoutMs) { RCF::ThreadInfoPtr tiPtr = getTlsThreadInfoPtr(); RCF::ThreadPool & threadPool = tiPtr->getThreadPool(); if (threadPool.shouldStop()) { return; } // poll the UDP socket for messages, and read a message if one is available fd_set fdSet; FD_ZERO(&fdSet); FD_SET( static_cast<SOCKET>(mFd), &fdSet); timeval timeout; timeout.tv_sec = timeoutMs/1000; timeout.tv_usec = 1000*(timeoutMs%1000); int ret = Platform::OS::BsdSockets::select( mFd+1, &fdSet, NULL, NULL, timeoutMs < 0 ? NULL : &timeout); int err = Platform::OS::BsdSockets::GetLastError(); if (ret == 1) { SessionStatePtr sessionStatePtr = getTlsUdpSessionStatePtr(); if (sessionStatePtr.get() == NULL) { sessionStatePtr = SessionStatePtr(new SessionState(*this)); SessionPtr sessionPtr = getSessionManager().createSession(); sessionPtr->setSessionState(*sessionStatePtr); sessionStatePtr->mSessionPtr = sessionPtr; setTlsUdpSessionStatePtr(sessionStatePtr); } { // read a message ReallocBufferPtr &readVecPtr = sessionStatePtr->mReadVecPtr; if (readVecPtr.get() == NULL || !readVecPtr.unique()) { readVecPtr.reset( new ReallocBuffer()); } ReallocBuffer &buffer = *readVecPtr; SockAddrStorage from; int fromlen = sizeof(from); memset(&from, 0, sizeof(from)); buffer.resize(4); int len = Platform::OS::BsdSockets::recvfrom( mFd, &buffer[0], 4, MSG_PEEK, (sockaddr *) &from, &fromlen); err = Platform::OS::BsdSockets::GetLastError(); sessionStatePtr->mRemoteAddress.init( (sockaddr&) from, fromlen, mIpAddress.getType()); if (!isIpAllowed(sessionStatePtr->mRemoteAddress)) { RCF_LOG_2()(sessionStatePtr->mRemoteAddress.getIp()) << "Client IP does not match server's IP access rules. Closing connection."; discardPacket(mFd); } else if ( len == 4 || (len == -1 && err == Platform::OS::BsdSockets::ERR_EMSGSIZE)) { unsigned int dataLength = 0; memcpy(&dataLength, &buffer[0], 4); networkToMachineOrder(&dataLength, 4, 1); if (getMaxMessageLength() && dataLength > getMaxMessageLength()) { ByteBuffer byteBuffer; encodeServerError(getSessionManager(), byteBuffer, RcfError_ServerMessageLength); byteBuffer.expandIntoLeftMargin(4); * (boost::uint32_t *) ( byteBuffer.getPtr() ) = static_cast<boost::uint32_t>(byteBuffer.getLength()-4); RCF::machineToNetworkOrder(byteBuffer.getPtr(), 4, 1); char *buffer = byteBuffer.getPtr(); std::size_t bufferLen = byteBuffer.getLength(); sockaddr * pRemoteAddr = NULL; Platform::OS::BsdSockets::socklen_t remoteAddrSize = 0; sessionStatePtr->mRemoteAddress.getSockAddr(pRemoteAddr, remoteAddrSize); int len = sendto( mFd, buffer, static_cast<int>(bufferLen), 0, pRemoteAddr, remoteAddrSize); RCF_UNUSED_VARIABLE(len); discardPacket(mFd); } else { buffer.resize(4+dataLength); memset(&from, 0, sizeof(from)); fromlen = sizeof(from); len = Platform::OS::BsdSockets::recvfrom( mFd, &buffer[0], 4+dataLength, 0, (sockaddr *) &from, &fromlen); if (static_cast<unsigned int>(len) == 4+dataLength) { getSessionManager().onReadCompleted(sessionStatePtr->mSessionPtr); } } } else { discardPacket(mFd); } } } else if (ret == 0) { //RCF_LOG_4()(mFd)(mPort)(timeoutMs) << "UdpServerTransport - no messages received within polling interval."; } else if (ret == -1) { Exception e( _RcfError_Socket("select()"), err, RcfSubsystem_Os); RCF_THROW(e)(mFd)(mIpAddress.string())(err); } }
void * asio_handler_allocate(std::size_t size, AmiTimerHandler * pHandler) { RCF_UNUSED_VARIABLE(pHandler); return gpAmiTimerHandlerCache->allocate(size); }
void ServerObjectService::onServerStop(RcfServer & server) { RCF_UNUSED_VARIABLE(server); mpRcfServer = NULL; mPeriodicTimer.stop(); }
void PublishingService::onServerStart(RcfServer &server) { RCF_UNUSED_VARIABLE(server); mPeriodicTimer.setIntervalMs(mPingIntervalMs); mPeriodicTimer.start(); }
void asio_handler_deallocate(void * pointer, std::size_t size, AmiIoHandler * pHandler) { RCF_UNUSED_VARIABLE(pHandler); return gpAmiIoHandlerCache->deallocate(pointer, size); }
void MulticastClientTransport::disconnect(unsigned int timeoutMs) { RCF_UNUSED_VARIABLE(timeoutMs); }
read_write_mutex(read_write_scheduling_policy rwsp) : readerCount(RCF_DEFAULT_INIT) { RCF_UNUSED_VARIABLE(rwsp); }
int MulticastClientTransport::send( ClientTransportCallback & clientStub, const std::vector<ByteBuffer> & data, unsigned int timeoutMs) { // NB: As the same buffer is sent on all transports, the transports and // filters should never modify the buffer. Any transport that transforms // data needs to do so in a separate per-transport buffer. RCF_UNUSED_VARIABLE(timeoutMs); RCF_LOG_2()(lengthByteBuffers(data))(timeoutMs) << "MulticastClientTransport::send() - entry."; mLastRequestSize = lengthByteBuffers(data); mRunningTotalBytesSent += mLastRequestSize; bringInNewTransports(); Lock lock(mClientTransportsMutex); std::size_t transportsInitial = mClientTransports.size(); PublishCompletionInfo info( mClientTransports.size() ); // Setup completion handlers. std::vector<PublishCompletionHandler> handlers( mClientTransports.size() ); for (std::size_t i=0; i<mClientTransports.size(); ++i) { ClientTransport * pTransport = (*mClientTransports[i]).get(); handlers[i] = PublishCompletionHandler(pTransport, &info); } // Async send on all transports. for (std::size_t i=0; i<handlers.size(); ++i) { try { handlers[i].mpClientTransport->setAsync(true); handlers[i].mpClientTransport->send(handlers[i], data, 0); } catch(const Exception &e) { Exception err( _RcfError_SyncPublishError(e.what()) ); handlers[i].onError(err); } } // Wait for async completions. boost::uint32_t completionDurationMs = 0; { Timer timer; info.wait(timeoutMs); completionDurationMs = timer.getDurationMs(); } // Cancel any outstanding sends. for (std::size_t i=0; i<handlers.size(); ++i) { if (!handlers[i].mCompleted) { (*mClientTransports[i])->cancel(); RCF_LOG_2()(i) << "MulticastClientTransport::send() - cancel send."; } } // Wait for canceled ops to complete. boost::uint32_t cancelDurationMs = 0; { Timer timer; info.wait(timeoutMs); cancelDurationMs = timer.getDurationMs(); } RCF_ASSERT(info.getCompletionCount() == handlers.size()); // Close and remove any subscriber transports with errors. std::size_t transportsRemoved = 0; for (std::size_t i=0; i<handlers.size(); ++i) { RCF_ASSERT(handlers[i].mCompleted); if (!handlers[i].mOk) { mClientTransports[i] = ClientTransportAutoPtrPtr(); ++transportsRemoved; RCF_LOG_2()(i)(handlers[i].mCompleted)(handlers[i].mOk)(handlers[i].mError) << "MulticastClientTransport::send() - remove subscriber transport."; } } eraseRemove(mClientTransports, ClientTransportAutoPtrPtr()); clientStub.onSendCompleted(); std::size_t transportsFinal = transportsInitial - transportsRemoved; RCF_LOG_2() (lengthByteBuffers(data))(completionDurationMs)(cancelDurationMs)(transportsInitial)(transportsFinal) << "MulticastClientTransport::send() - exit."; return 1; }
void MulticastClientTransport::connect(ClientTransportCallback &clientStub, unsigned int timeoutMs) { RCF_UNUSED_VARIABLE(clientStub); RCF_UNUSED_VARIABLE(timeoutMs); clientStub.onConnectCompleted(true); }
void onConnectCompleted(bool alreadyConnected = false) { RCF_UNUSED_VARIABLE(alreadyConnected); RCF_ASSERT(0); }
void UdpServerTransport::cycle( int timeoutMs, const volatile bool &) //stopFlag { // poll the UDP socket for messages, and read a message if one is available fd_set fdSet; FD_ZERO(&fdSet); FD_SET( static_cast<SOCKET>(mFd), &fdSet); timeval timeout; timeout.tv_sec = timeoutMs/1000; timeout.tv_usec = 1000*(timeoutMs%1000); int ret = Platform::OS::BsdSockets::select( mFd+1, &fdSet, NULL, NULL, timeoutMs < 0 ? NULL : &timeout); int err = Platform::OS::BsdSockets::GetLastError(); if (ret == 1) { SessionStatePtr sessionStatePtr = getCurrentUdpSessionStatePtr(); if (sessionStatePtr.get() == NULL) { sessionStatePtr = SessionStatePtr(new SessionState(*this)); SessionPtr sessionPtr = getSessionManager().createSession(); sessionPtr->setProactor(*sessionStatePtr); sessionStatePtr->mSessionPtr = sessionPtr; setCurrentUdpSessionStatePtr(sessionStatePtr); RcfSessionPtr rcfSessionPtr = boost::static_pointer_cast<RcfSession>(sessionPtr); rcfSessionPtr->mIoState = RcfSession::Reading; } { // read a message boost::shared_ptr<std::vector<char> > &readVecPtr = sessionStatePtr->mReadVecPtr; if (readVecPtr.get() == NULL || !readVecPtr.unique()) { readVecPtr.reset( new std::vector<char>()); } std::vector<char> &buffer = *readVecPtr; sockaddr from; int fromlen = sizeof(from); memset(&from, 0, sizeof(from)); buffer.resize(4); int len = Platform::OS::BsdSockets::recvfrom( mFd, &buffer[0], 4, MSG_PEEK, &from, &fromlen); err = Platform::OS::BsdSockets::GetLastError(); if (isClientAddrAllowed( *(sockaddr_in *) &from ) && (len == 4 || (len == -1 && err == Platform::OS::BsdSockets::ERR_EMSGSIZE))) { sockaddr_in *remoteAddr = reinterpret_cast<sockaddr_in*>(&from); sessionStatePtr->remoteAddress = IpAddress(*remoteAddr); unsigned int dataLength = 0; memcpy(&dataLength, &buffer[0], 4); networkToMachineOrder(&dataLength, 4, 1); if (dataLength <= static_cast<unsigned int>(getMaxMessageLength())) { buffer.resize(4+dataLength); memset(&from, 0, sizeof(from)); fromlen = sizeof(from); len = Platform::OS::BsdSockets::recvfrom( mFd, &buffer[0], 4+dataLength, 0, &from, &fromlen); if (static_cast<unsigned int>(len) == 4+dataLength) { getSessionManager().onReadCompleted(sessionStatePtr->mSessionPtr); } } else { ByteBuffer byteBuffer; encodeServerError(byteBuffer, RcfError_ServerMessageLength); byteBuffer.expandIntoLeftMargin(4); * (boost::uint32_t *) ( byteBuffer.getPtr() ) = static_cast<boost::uint32_t>(byteBuffer.getLength()-4); RCF::machineToNetworkOrder(byteBuffer.getPtr(), 4, 1); char *buffer = byteBuffer.getPtr(); std::size_t bufferLen = byteBuffer.getLength(); const sockaddr_in &remoteAddr = sessionStatePtr->remoteAddress.getSockAddr(); int len = sendto( mFd, buffer, static_cast<int>(bufferLen), 0, (const sockaddr *) &remoteAddr, sizeof(remoteAddr)); RCF_UNUSED_VARIABLE(len); discardPacket(mFd); } } else { // discard the message (sender ip not allowed, or message format bad) discardPacket(mFd); } } } else if (ret == 0) { RCF_TRACE("server udp poll - no messages")(mFd)(mPort); } else if (ret == -1) { RCF_THROW( Exception( RcfError_Socket, err, RcfSubsystem_Os, "udp server select() failed ")) (mFd)(mPort)(err); } }
void XorFilter::onWriteCompleted(std::size_t bytesTransferred, int error) { RCF_UNUSED_VARIABLE(error); // TODO: error handling getPreFilter().onWriteCompleted(bytesTransferred, 0); }
void UdpSessionState::getTransportFilters(std::vector<FilterPtr> &filters) { RCF_UNUSED_VARIABLE(filters); RCF_ASSERT(0); }
void cancelConnect(int fd) { RCF_UNUSED_VARIABLE(fd); }
void PingBackService::onServiceRemoved(RcfServer &server) { RCF_UNUSED_VARIABLE(server); }
// returns -2 for timeout, -1 for error, otherwise number of bytes sent (> 0) int timedSend( I_PollingFunctor &pollingFunctor, int &err, int fd, const std::vector<ByteBuffer> &byteBuffers, std::size_t maxSendSize, int flags) { RCF_UNUSED_VARIABLE(flags); std::size_t bytesRemaining = lengthByteBuffers(byteBuffers); std::size_t bytesSent = 0; while (true) { std::size_t bytesToSend = RCF_MIN(bytesRemaining, maxSendSize); ThreadLocalCached< std::vector<WSABUF> > tlcWsabufs; std::vector<WSABUF> &wsabufs = tlcWsabufs.get(); forEachByteBuffer( boost::bind(&appendWsabuf, boost::ref(wsabufs), _1), byteBuffers, bytesSent, bytesToSend); int count = 0; int myErr = 0; #ifdef BOOST_WINDOWS { DWORD cbSent = 0; int ret = WSASend( fd, &wsabufs[0], static_cast<DWORD>(wsabufs.size()), &cbSent, 0, NULL, NULL); count = (ret == 0) ? cbSent : -1; myErr = Platform::OS::BsdSockets::GetLastError(); } #else { msghdr hdr = {0}; hdr.msg_iov = &wsabufs[0]; hdr.msg_iovlen = wsabufs.size(); count = sendmsg(fd, &hdr, 0); myErr = Platform::OS::BsdSockets::GetLastError(); } #endif //int myErr = WSAGetLastError(); //int myErr = Platform::OS::BsdSockets::GetLastError() //if (ret == 0) if (count >= 0) { RCF_ASSERT_LTEQ(count , static_cast<int>(bytesRemaining)); bytesRemaining -= count;//cbSent; bytesSent += count;//cbSent; err = 0; return static_cast<int>(bytesSent); } //else if (myErr == WSAEWOULDBLOCK) else if (myErr == Platform::OS::BsdSockets::ERR_EWOULDBLOCK) { // can't get WSA_IO_PENDING here, since the socket isn't overlapped int ret = pollingFunctor(fd, myErr, false); if (ret != 0) { err = myErr; return ret; } } else { err = myErr; return -1; } } }