face: override Transport::beforeChangePersistency in all subclasses
This commit also adds the final specifier to some Transport
subclasses in order to improve code generation.
Change-Id: If2979fa1614476a98019ba79cee3961663fc447b
Refs: #3318
diff --git a/daemon/face/datagram-transport.hpp b/daemon/face/datagram-transport.hpp
index f9cf2fc..b435a18 100644
--- a/daemon/face/datagram-transport.hpp
+++ b/daemon/face/datagram-transport.hpp
@@ -54,12 +54,6 @@
explicit
DatagramTransport(typename protocol::socket&& socket);
- virtual void
- doSend(Transport::Packet&& packet) DECL_OVERRIDE;
-
- virtual void
- doClose() DECL_OVERRIDE;
-
/** \brief Receive datagram, translate buffer into packet, deliver to parent class.
*/
void
@@ -67,15 +61,21 @@
const boost::system::error_code& error);
protected:
- void
- handleReceive(const boost::system::error_code& error,
- size_t nBytesReceived);
+ virtual void
+ doClose() DECL_OVERRIDE;
+
+ virtual void
+ doSend(Transport::Packet&& packet) DECL_OVERRIDE;
void
handleSend(const boost::system::error_code& error,
size_t nBytesSent, const Block& payload);
void
+ handleReceive(const boost::system::error_code& error,
+ size_t nBytesReceived);
+
+ void
processErrorCode(const boost::system::error_code& error);
bool
@@ -96,7 +96,6 @@
template<class T, class U>
-inline
DatagramTransport<T, U>::DatagramTransport(typename DatagramTransport::protocol::socket&& socket)
: m_socket(std::move(socket))
{
@@ -107,20 +106,7 @@
}
template<class T, class U>
-inline void
-DatagramTransport<T, U>::doSend(Transport::Packet&& packet)
-{
- NFD_LOG_FACE_TRACE(__func__);
-
- m_socket.async_send(boost::asio::buffer(packet.packet),
- bind(&DatagramTransport<T, U>::handleSend, this,
- boost::asio::placeholders::error,
- boost::asio::placeholders::bytes_transferred,
- packet.packet));
-}
-
-template<class T, class U>
-inline void
+void
DatagramTransport<T, U>::doClose()
{
NFD_LOG_FACE_TRACE(__func__);
@@ -141,7 +127,20 @@
}
template<class T, class U>
-inline void
+void
+DatagramTransport<T, U>::doSend(Transport::Packet&& packet)
+{
+ NFD_LOG_FACE_TRACE(__func__);
+
+ m_socket.async_send(boost::asio::buffer(packet.packet),
+ bind(&DatagramTransport<T, U>::handleSend, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ packet.packet));
+}
+
+template<class T, class U>
+void
DatagramTransport<T, U>::receiveDatagram(const uint8_t* buffer, size_t nBytesReceived,
const boost::system::error_code& error)
{
@@ -169,7 +168,7 @@
}
template<class T, class U>
-inline void
+void
DatagramTransport<T, U>::handleReceive(const boost::system::error_code& error,
size_t nBytesReceived)
{
@@ -183,7 +182,7 @@
}
template<class T, class U>
-inline void
+void
DatagramTransport<T, U>::handleSend(const boost::system::error_code& error,
size_t nBytesSent, const Block& payload)
// 'payload' is unused; it's needed to retain the underlying Buffer
@@ -195,7 +194,7 @@
}
template<class T, class U>
-inline void
+void
DatagramTransport<T, U>::processErrorCode(const boost::system::error_code& error)
{
NFD_LOG_FACE_TRACE(__func__);
diff --git a/daemon/face/internal-transport.cpp b/daemon/face/internal-transport.cpp
index 070a4b5..cc3e0a6 100644
--- a/daemon/face/internal-transport.cpp
+++ b/daemon/face/internal-transport.cpp
@@ -46,6 +46,15 @@
}
void
+InternalForwarderTransport::beforeChangePersistency(ndn::nfd::FacePersistency newPersistency)
+{
+ if (newPersistency != ndn::nfd::FACE_PERSISTENCY_PERMANENT) {
+ BOOST_THROW_EXCEPTION(
+ std::invalid_argument("InternalForwarderTransport supports only FACE_PERSISTENCY_PERMANENT"));
+ }
+}
+
+void
InternalForwarderTransport::receiveFromLink(const Block& packet)
{
NFD_LOG_FACE_TRACE(__func__);
diff --git a/daemon/face/internal-transport.hpp b/daemon/face/internal-transport.hpp
index a282638..53bd379 100644
--- a/daemon/face/internal-transport.hpp
+++ b/daemon/face/internal-transport.hpp
@@ -63,6 +63,9 @@
protected:
virtual void
+ beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) DECL_OVERRIDE;
+
+ virtual void
doClose() DECL_OVERRIDE;
private:
diff --git a/daemon/face/multicast-udp-transport.cpp b/daemon/face/multicast-udp-transport.cpp
index a1f376b..544b4ff 100644
--- a/daemon/face/multicast-udp-transport.cpp
+++ b/daemon/face/multicast-udp-transport.cpp
@@ -51,6 +51,15 @@
}
void
+MulticastUdpTransport::beforeChangePersistency(ndn::nfd::FacePersistency newPersistency)
+{
+ if (newPersistency != ndn::nfd::FACE_PERSISTENCY_PERMANENT) {
+ BOOST_THROW_EXCEPTION(
+ std::invalid_argument("MulticastUdpTransport supports only FACE_PERSISTENCY_PERMANENT"));
+ }
+}
+
+void
MulticastUdpTransport::doSend(Transport::Packet&& packet)
{
NFD_LOG_FACE_TRACE(__func__);
diff --git a/daemon/face/multicast-udp-transport.hpp b/daemon/face/multicast-udp-transport.hpp
index 14371f7..2998f42 100644
--- a/daemon/face/multicast-udp-transport.hpp
+++ b/daemon/face/multicast-udp-transport.hpp
@@ -34,7 +34,7 @@
/**
* \brief A Transport that communicates on a UDP multicast group
*/
-class MulticastUdpTransport : public DatagramTransport<boost::asio::ip::udp, Multicast>
+class MulticastUdpTransport DECL_FINAL : public DatagramTransport<boost::asio::ip::udp, Multicast>
{
public:
/**
@@ -46,14 +46,19 @@
*/
MulticastUdpTransport(const protocol::endpoint& localEndpoint,
const protocol::endpoint& multicastGroup,
- protocol::socket&& recvSocket, protocol::socket&& sendSocket);
+ protocol::socket&& recvSocket,
+ protocol::socket&& sendSocket);
+
+protected:
+ virtual void
+ beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) DECL_FINAL;
private:
virtual void
- doSend(Transport::Packet&& packet) DECL_OVERRIDE;
+ doSend(Transport::Packet&& packet) DECL_FINAL;
virtual void
- doClose() DECL_OVERRIDE;
+ doClose() DECL_FINAL;
private:
protocol::endpoint m_multicastGroup;
diff --git a/daemon/face/stream-transport.hpp b/daemon/face/stream-transport.hpp
index e9ec78d..1c9b720 100644
--- a/daemon/face/stream-transport.hpp
+++ b/daemon/face/stream-transport.hpp
@@ -51,16 +51,16 @@
explicit
StreamTransport(typename protocol::socket&& socket);
- virtual void
- doSend(Transport::Packet&& packet) DECL_OVERRIDE;
-
+protected:
virtual void
doClose() DECL_OVERRIDE;
-protected:
void
deferredClose();
+ virtual void
+ doSend(Transport::Packet&& packet) DECL_OVERRIDE;
+
void
sendFromQueue();
@@ -81,42 +81,25 @@
NFD_LOG_INCLASS_DECLARE();
private:
- uint8_t m_inputBuffer[ndn::MAX_NDN_PACKET_SIZE];
- size_t m_inputBufferSize;
+ uint8_t m_receiveBuffer[ndn::MAX_NDN_PACKET_SIZE];
+ size_t m_receiveBufferSize;
std::queue<Block> m_sendQueue;
};
-// All derived classes must use
-// NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(StreamTransport, <specialization-parameter>, "Name");
-
template<class T>
-inline
StreamTransport<T>::StreamTransport(typename StreamTransport::protocol::socket&& socket)
: m_socket(std::move(socket))
- , m_inputBufferSize(0)
+ , m_receiveBufferSize(0)
{
- m_socket.async_receive(boost::asio::buffer(m_inputBuffer, ndn::MAX_NDN_PACKET_SIZE),
+ m_socket.async_receive(boost::asio::buffer(m_receiveBuffer, ndn::MAX_NDN_PACKET_SIZE),
bind(&StreamTransport<T>::handleReceive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
template<class T>
-inline void
-StreamTransport<T>::doSend(Transport::Packet&& packet)
-{
- NFD_LOG_FACE_TRACE(__func__);
-
- bool wasQueueEmpty = m_sendQueue.empty();
- m_sendQueue.push(packet.packet);
-
- if (wasQueueEmpty)
- sendFromQueue();
-}
-
-template<class T>
-inline void
+void
StreamTransport<T>::doClose()
{
NFD_LOG_FACE_TRACE(__func__);
@@ -148,7 +131,7 @@
}
template<class T>
-inline void
+void
StreamTransport<T>::deferredClose()
{
NFD_LOG_FACE_TRACE(__func__);
@@ -165,7 +148,20 @@
}
template<class T>
-inline void
+void
+StreamTransport<T>::doSend(Transport::Packet&& packet)
+{
+ NFD_LOG_FACE_TRACE(__func__);
+
+ bool wasQueueEmpty = m_sendQueue.empty();
+ m_sendQueue.push(packet.packet);
+
+ if (wasQueueEmpty)
+ sendFromQueue();
+}
+
+template<class T>
+void
StreamTransport<T>::sendFromQueue()
{
boost::asio::async_write(m_socket, boost::asio::buffer(m_sendQueue.front()),
@@ -175,7 +171,7 @@
}
template<class T>
-inline void
+void
StreamTransport<T>::handleSend(const boost::system::error_code& error,
size_t nBytesSent)
{
@@ -192,7 +188,7 @@
}
template<class T>
-inline void
+void
StreamTransport<T>::handleReceive(const boost::system::error_code& error,
size_t nBytesReceived)
{
@@ -201,26 +197,24 @@
NFD_LOG_FACE_TRACE("Received: " << nBytesReceived << " bytes");
- m_inputBufferSize += nBytesReceived;
+ m_receiveBufferSize += nBytesReceived;
size_t offset = 0;
bool isOk = true;
Block element;
- while (m_inputBufferSize - offset > 0) {
- std::tie(isOk, element) = Block::fromBuffer(m_inputBuffer + offset, m_inputBufferSize - offset);
+ while (m_receiveBufferSize - offset > 0) {
+ std::tie(isOk, element) = Block::fromBuffer(m_receiveBuffer + offset, m_receiveBufferSize - offset);
if (!isOk)
break;
offset += element.size();
+ BOOST_ASSERT(offset <= m_receiveBufferSize);
- BOOST_ASSERT(offset <= m_inputBufferSize);
-
- Transport::Packet packet(std::move(element));
- this->receive(std::move(packet));
+ this->receive(Transport::Packet(std::move(element)));
}
- if (!isOk && m_inputBufferSize == ndn::MAX_NDN_PACKET_SIZE && offset == 0) {
+ if (!isOk && m_receiveBufferSize == ndn::MAX_NDN_PACKET_SIZE && offset == 0) {
NFD_LOG_FACE_WARN("Failed to parse incoming packet or packet too large to process");
this->setState(TransportState::FAILED);
doClose();
@@ -228,24 +222,24 @@
}
if (offset > 0) {
- if (offset != m_inputBufferSize) {
- std::copy(m_inputBuffer + offset, m_inputBuffer + m_inputBufferSize, m_inputBuffer);
- m_inputBufferSize -= offset;
+ if (offset != m_receiveBufferSize) {
+ std::copy(m_receiveBuffer + offset, m_receiveBuffer + m_receiveBufferSize, m_receiveBuffer);
+ m_receiveBufferSize -= offset;
}
else {
- m_inputBufferSize = 0;
+ m_receiveBufferSize = 0;
}
}
- m_socket.async_receive(boost::asio::buffer(m_inputBuffer + m_inputBufferSize,
- ndn::MAX_NDN_PACKET_SIZE - m_inputBufferSize),
+ m_socket.async_receive(boost::asio::buffer(m_receiveBuffer + m_receiveBufferSize,
+ ndn::MAX_NDN_PACKET_SIZE - m_receiveBufferSize),
bind(&StreamTransport<T>::handleReceive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
template<class T>
-inline void
+void
StreamTransport<T>::processErrorCode(const boost::system::error_code& error)
{
NFD_LOG_FACE_TRACE(__func__);
diff --git a/daemon/face/tcp-transport.hpp b/daemon/face/tcp-transport.hpp
index 654f224..b2d9fcf 100644
--- a/daemon/face/tcp-transport.hpp
+++ b/daemon/face/tcp-transport.hpp
@@ -33,7 +33,7 @@
/**
* \brief A Transport that communicates on a connected TCP socket
*/
-class TcpTransport : public StreamTransport<boost::asio::ip::tcp>
+class TcpTransport DECL_FINAL : public StreamTransport<boost::asio::ip::tcp>
{
public:
TcpTransport(protocol::socket&& socket,
@@ -41,7 +41,7 @@
protected:
virtual void
- beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) DECL_OVERRIDE;
+ beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) DECL_FINAL;
};
} // namespace face
diff --git a/daemon/face/transport.cpp b/daemon/face/transport.cpp
index 0c4f4ee..1b7832e 100644
--- a/daemon/face/transport.cpp
+++ b/daemon/face/transport.cpp
@@ -128,6 +128,25 @@
}
void
+Transport::setPersistency(ndn::nfd::FacePersistency newPersistency)
+{
+ if (m_persistency == newPersistency) {
+ return;
+ }
+
+ if (newPersistency == ndn::nfd::FACE_PERSISTENCY_NONE) {
+ throw std::runtime_error("invalid persistency transition");
+ }
+
+ if (m_persistency != ndn::nfd::FACE_PERSISTENCY_NONE) {
+ this->beforeChangePersistency(newPersistency);
+ NFD_LOG_FACE_DEBUG("setPersistency " << m_persistency << " -> " << newPersistency);
+ }
+
+ m_persistency = newPersistency;
+}
+
+void
Transport::setState(TransportState newState)
{
if (m_state == newState) {
diff --git a/daemon/face/transport.hpp b/daemon/face/transport.hpp
index 55efe3b..d069a0e 100644
--- a/daemon/face/transport.hpp
+++ b/daemon/face/transport.hpp
@@ -237,13 +237,9 @@
/** \brief invoked before persistency is changed
* \throw std::invalid_argument new persistency is not supported
* \throw std::runtime_error transition is disallowed
- *
- * Base class implementation does nothing.
*/
virtual void
- beforeChangePersistency(ndn::nfd::FacePersistency newPersistency)
- {
- }
+ beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) = 0;
/** \brief performs Transport specific operations to close the transport
*
@@ -337,13 +333,6 @@
return m_persistency;
}
-inline void
-Transport::setPersistency(ndn::nfd::FacePersistency persistency)
-{
- this->beforeChangePersistency(persistency);
- m_persistency = persistency;
-}
-
inline ndn::nfd::LinkType
Transport::getLinkType() const
{
diff --git a/daemon/face/unicast-udp-transport.cpp b/daemon/face/unicast-udp-transport.cpp
index a5fb3e7..3bd4759 100644
--- a/daemon/face/unicast-udp-transport.cpp
+++ b/daemon/face/unicast-udp-transport.cpp
@@ -41,10 +41,9 @@
UnicastUdpTransport::UnicastUdpTransport(protocol::socket&& socket,
ndn::nfd::FacePersistency persistency,
- const time::seconds& idleTimeout)
+ time::nanoseconds idleTimeout)
: DatagramTransport(std::move(socket))
, m_idleTimeout(idleTimeout)
- , m_lastIdleCheck(time::steady_clock::now())
{
this->setLocalUri(FaceUri(m_socket.local_endpoint()));
this->setRemoteUri(FaceUri(m_socket.remote_endpoint()));
@@ -76,29 +75,36 @@
#endif
if (getPersistency() == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND &&
- m_idleTimeout > time::seconds::zero()) {
- m_closeIfIdleEvent = scheduler::schedule(m_idleTimeout, bind(&UnicastUdpTransport::closeIfIdle, this));
+ m_idleTimeout > time::nanoseconds::zero()) {
+ scheduleClosureWhenIdle();
}
}
void
-UnicastUdpTransport::closeIfIdle()
+UnicastUdpTransport::beforeChangePersistency(ndn::nfd::FacePersistency newPersistency)
{
- // transport can be switched from on-demand to non-on-demand mode
- // (non-on-demand -> on-demand transition is not allowed)
- if (getPersistency() == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
+ if (newPersistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND &&
+ m_idleTimeout > time::nanoseconds::zero()) {
+ scheduleClosureWhenIdle();
+ }
+ else {
+ m_closeIfIdleEvent.cancel();
+ }
+}
+
+void
+UnicastUdpTransport::scheduleClosureWhenIdle()
+{
+ m_closeIfIdleEvent = scheduler::schedule(m_idleTimeout, [this] {
if (!hasBeenUsedRecently()) {
NFD_LOG_FACE_INFO("Closing due to inactivity");
this->close();
}
else {
resetRecentUsage();
-
- m_lastIdleCheck = time::steady_clock::now();
- m_closeIfIdleEvent = scheduler::schedule(m_idleTimeout, bind(&UnicastUdpTransport::closeIfIdle, this));
+ scheduleClosureWhenIdle();
}
- }
- // else do nothing and do not reschedule the event
+ });
}
} // namespace face
diff --git a/daemon/face/unicast-udp-transport.hpp b/daemon/face/unicast-udp-transport.hpp
index 0a9beed..0c7c277 100644
--- a/daemon/face/unicast-udp-transport.hpp
+++ b/daemon/face/unicast-udp-transport.hpp
@@ -35,20 +35,23 @@
/**
* \brief A Transport that communicates on a unicast UDP socket
*/
-class UnicastUdpTransport : public DatagramTransport<boost::asio::ip::udp, Unicast>
+class UnicastUdpTransport DECL_FINAL : public DatagramTransport<boost::asio::ip::udp, Unicast>
{
public:
UnicastUdpTransport(protocol::socket&& socket,
ndn::nfd::FacePersistency persistency,
- const time::seconds& idleTimeout);
+ time::nanoseconds idleTimeout);
+
+protected:
+ virtual void
+ beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) DECL_FINAL;
private:
void
- closeIfIdle();
+ scheduleClosureWhenIdle();
private:
- const time::seconds m_idleTimeout;
- time::steady_clock::TimePoint m_lastIdleCheck;
+ const time::nanoseconds m_idleTimeout;
scheduler::ScopedEventId m_closeIfIdleEvent;
};
diff --git a/daemon/face/unix-stream-transport.cpp b/daemon/face/unix-stream-transport.cpp
index 0e37a42..6df0efb 100644
--- a/daemon/face/unix-stream-transport.cpp
+++ b/daemon/face/unix-stream-transport.cpp
@@ -49,5 +49,14 @@
NFD_LOG_FACE_INFO("Creating transport");
}
+void
+UnixStreamTransport::beforeChangePersistency(ndn::nfd::FacePersistency newPersistency)
+{
+ if (newPersistency != ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
+ BOOST_THROW_EXCEPTION(
+ std::invalid_argument("UnixStreamTransport supports only FACE_PERSISTENCY_ON_DEMAND"));
+ }
+}
+
} // namespace face
} // namespace nfd
diff --git a/daemon/face/unix-stream-transport.hpp b/daemon/face/unix-stream-transport.hpp
index 27f4eaa..dc6e74e 100644
--- a/daemon/face/unix-stream-transport.hpp
+++ b/daemon/face/unix-stream-transport.hpp
@@ -38,11 +38,15 @@
/**
* \brief A Transport that communicates on a stream-oriented Unix domain socket
*/
-class UnixStreamTransport : public StreamTransport<boost::asio::local::stream_protocol>
+class UnixStreamTransport DECL_FINAL : public StreamTransport<boost::asio::local::stream_protocol>
{
public:
explicit
UnixStreamTransport(protocol::socket&& socket);
+
+protected:
+ virtual void
+ beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) DECL_FINAL;
};
} // namespace face
diff --git a/daemon/face/websocket-transport.cpp b/daemon/face/websocket-transport.cpp
index 4fbed81..cf3da37 100644
--- a/daemon/face/websocket-transport.cpp
+++ b/daemon/face/websocket-transport.cpp
@@ -56,7 +56,8 @@
NFD_LOG_FACE_INFO("Creating transport");
}
-void WebSocketTransport::beforeChangePersistency(ndn::nfd::FacePersistency newPersistency)
+void
+WebSocketTransport::beforeChangePersistency(ndn::nfd::FacePersistency newPersistency)
{
if (newPersistency != ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
BOOST_THROW_EXCEPTION(
diff --git a/daemon/face/websocket-transport.hpp b/daemon/face/websocket-transport.hpp
index 6bfbdc3..91a99c1 100644
--- a/daemon/face/websocket-transport.hpp
+++ b/daemon/face/websocket-transport.hpp
@@ -36,7 +36,7 @@
/**
* \brief A Transport that communicates on a WebSocket connection
*/
-class WebSocketTransport : public Transport
+class WebSocketTransport DECL_FINAL : public Transport
{
public:
WebSocketTransport(websocketpp::connection_hdl hdl,
@@ -57,14 +57,14 @@
protected:
virtual void
- beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) DECL_OVERRIDE;
+ beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) DECL_FINAL;
virtual void
- doClose() DECL_OVERRIDE;
+ doClose() DECL_FINAL;
private:
virtual void
- doSend(Transport::Packet&& packet) DECL_OVERRIDE;
+ doSend(Transport::Packet&& packet) DECL_FINAL;
void
schedulePing();