transport: replace a bunch of bools with a proper state machine
Change-Id: I42f74aebfd714cd8b3be7fcb3068228935482366
diff --git a/ndn-cxx/face.cpp b/ndn-cxx/face.cpp
index ed340e5..4a19701 100644
--- a/ndn-cxx/face.cpp
+++ b/ndn-cxx/face.cpp
@@ -292,7 +292,7 @@
{
IO_CAPTURE_WEAK_IMPL(post) {
impl->shutdown();
- if (m_transport->isConnected())
+ if (m_transport->getState() != Transport::State::CLOSED)
m_transport->close();
} IO_CAPTURE_WEAK_IMPL_END
}
diff --git a/ndn-cxx/impl/face-impl.hpp b/ndn-cxx/impl/face-impl.hpp
index 1f28ca7..239885d 100644
--- a/ndn-cxx/impl/face-impl.hpp
+++ b/ndn-cxx/impl/face-impl.hpp
@@ -304,12 +304,12 @@
void
ensureConnected(bool wantResume)
{
- if (!m_face.m_transport->isConnected()) {
+ if (m_face.m_transport->getState() == Transport::State::CLOSED) {
m_face.m_transport->connect(m_face.getIoService(),
[this] (const Block& wire) { m_face.onReceiveElement(wire); });
}
- if (wantResume && !m_face.m_transport->isReceiving()) {
+ if (wantResume) {
m_face.m_transport->resume();
}
}
diff --git a/ndn-cxx/transport/detail/stream-transport-impl.hpp b/ndn-cxx/transport/detail/stream-transport-impl.hpp
index f11a622..4c52005 100644
--- a/ndn-cxx/transport/detail/stream-transport-impl.hpp
+++ b/ndn-cxx/transport/detail/stream-transport-impl.hpp
@@ -55,10 +55,10 @@
void
connect(const typename Protocol::endpoint& endpoint)
{
- if (m_isConnecting) {
+ if (m_transport.getState() == Transport::State::CONNECTING) {
return;
}
- m_isConnecting = true;
+ m_transport.setState(Transport::State::CONNECTING);
// Wait at most 4 seconds to connect
/// @todo Decide whether this number should be configurable
@@ -76,38 +76,30 @@
void
close()
{
- m_isConnecting = false;
+ m_transport.setState(Transport::State::CLOSED);
boost::system::error_code error; // to silently ignore all errors
m_connectTimer.cancel(error);
m_socket.cancel(error);
m_socket.close(error);
- m_transport.m_isConnected = false;
- m_transport.m_isReceiving = false;
TransmissionQueue{}.swap(m_transmissionQueue); // clear the queue
}
void
pause()
{
- if (m_isConnecting)
- return;
-
- if (m_transport.m_isReceiving) {
- m_transport.m_isReceiving = false;
+ if (m_transport.getState() == Transport::State::RUNNING) {
m_socket.cancel();
+ m_transport.setState(Transport::State::PAUSED);
}
}
void
resume()
{
- if (m_isConnecting)
- return;
-
- if (!m_transport.m_isReceiving) {
- m_transport.m_isReceiving = true;
+ if (m_transport.getState() == Transport::State::PAUSED) {
+ m_transport.setState(Transport::State::RUNNING);
m_inputBufferSize = 0;
asyncReceive();
}
@@ -118,7 +110,9 @@
{
m_transmissionQueue.push(block);
- if (m_transport.m_isConnected && m_transmissionQueue.size() == 1) {
+ if (m_transport.getState() != Transport::State::CLOSED &&
+ m_transport.getState() != Transport::State::CONNECTING &&
+ m_transmissionQueue.size() == 1) {
asyncWrite();
}
// if not connected or there's another transmission in progress (m_transmissionQueue.size() > 1),
@@ -129,16 +123,14 @@
void
connectHandler(const boost::system::error_code& error)
{
- m_isConnecting = false;
m_connectTimer.cancel();
if (error) {
- m_transport.m_isConnected = false;
m_transport.close();
NDN_THROW(Transport::Error(error, "error while connecting to the forwarder"));
}
- m_transport.m_isConnected = true;
+ m_transport.setState(Transport::State::PAUSED);
if (!m_transmissionQueue.empty()) {
resume();
@@ -172,8 +164,8 @@
NDN_THROW(Transport::Error(error, "error while writing data to socket"));
}
- if (!m_transport.m_isConnected) {
- return; // queue has been already cleared
+ if (m_transport.getState() == Transport::State::CLOSED) {
+ return; // queue has already been cleared
}
BOOST_ASSERT(!m_transmissionQueue.empty());
@@ -249,7 +241,6 @@
size_t m_inputBufferSize = 0;
TransmissionQueue m_transmissionQueue;
boost::asio::steady_timer m_connectTimer;
- bool m_isConnecting = false;
};
} // namespace detail
diff --git a/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp b/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp
index ded87f6..61c7d27 100644
--- a/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp
+++ b/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp
@@ -42,10 +42,10 @@
void
connect(const typename Protocol::resolver::query& query)
{
- if (this->m_isConnecting) {
+ if (this->m_transport.getState() == Transport::State::CONNECTING) {
return;
}
- this->m_isConnecting = true;
+ this->m_transport.setState(Transport::State::CONNECTING);
// Wait at most 4 seconds to connect
/// @todo Decide whether this number should be configurable
diff --git a/ndn-cxx/transport/transport.hpp b/ndn-cxx/transport/transport.hpp
index 6fd4374..2ef4b3d 100644
--- a/ndn-cxx/transport/transport.hpp
+++ b/ndn-cxx/transport/transport.hpp
@@ -30,7 +30,8 @@
namespace ndn {
-/** \brief Provides TLV-block delivery service.
+/**
+ * \brief Provides a "TLV-oriented" delivery service.
*/
class Transport : noncopyable
{
@@ -43,9 +44,16 @@
Error(const boost::system::error_code& code, const std::string& msg);
};
- using ReceiveCallback = std::function<void(const Block& wire)>;
- using ErrorCallback = std::function<void()>;
+ enum class State {
+ CLOSED,
+ CONNECTING,
+ RUNNING,
+ PAUSED,
+ };
+ using ReceiveCallback = std::function<void(const Block&)>;
+
+public:
virtual
~Transport() = default;
@@ -89,29 +97,27 @@
resume() = 0;
/**
- * \brief Return whether the transport is connected.
+ * \brief Return the current state of the transport.
*/
- bool
- isConnected() const noexcept
+ State
+ getState() const noexcept
{
- return m_isConnected;
+ return m_state;
}
- /**
- * \retval true incoming packets are expected, the receive callback will be invoked
- * \retval false incoming packets are not expected, the receive callback will not be invoked
- */
- bool
- isReceiving() const noexcept
+protected:
+ void
+ setState(State state) noexcept
{
- return m_isReceiving;
+ m_state = state;
}
protected:
boost::asio::io_service* m_ioService = nullptr;
ReceiveCallback m_receiveCallback;
- bool m_isConnected = false;
- bool m_isReceiving = false;
+
+private:
+ State m_state = State::CLOSED;
};
} // namespace ndn