faces: Replace deadline_timer usage in TcpChannel with Scheduler-based events
Change-Id: I37a7a3203b3187e029697a21e3314cfacbbed314
Refs: #1368
diff --git a/daemon/face/tcp-channel.cpp b/daemon/face/tcp-channel.cpp
index cd2fb4f..d058944 100644
--- a/daemon/face/tcp-channel.cpp
+++ b/daemon/face/tcp-channel.cpp
@@ -83,18 +83,14 @@
shared_ptr<ip::tcp::socket> clientSocket =
make_shared<ip::tcp::socket>(ref(getGlobalIoService()));
- shared_ptr<ndn::monotonic_deadline_timer> connectTimeoutTimer =
- make_shared<ndn::monotonic_deadline_timer>(ref(getGlobalIoService()));
+ EventId connectTimeoutEvent = scheduler::schedule(timeout,
+ bind(&TcpChannel::handleFailedConnect, this,
+ clientSocket, onConnectFailed));
clientSocket->async_connect(remoteEndpoint,
bind(&TcpChannel::handleSuccessfulConnect, this, _1,
- clientSocket, connectTimeoutTimer,
+ clientSocket, connectTimeoutEvent,
onFaceCreated, onConnectFailed));
-
- connectTimeoutTimer->expires_from_now(timeout);
- connectTimeoutTimer->async_wait(bind(&TcpChannel::handleFailedConnect, this, _1,
- clientSocket, connectTimeoutTimer,
- onConnectFailed));
}
void
@@ -106,23 +102,19 @@
shared_ptr<ip::tcp::socket> clientSocket =
make_shared<ip::tcp::socket>(ref(getGlobalIoService()));
- shared_ptr<ndn::monotonic_deadline_timer> connectTimeoutTimer =
- make_shared<ndn::monotonic_deadline_timer>(ref(getGlobalIoService()));
-
ip::tcp::resolver::query query(remoteHost, remotePort);
shared_ptr<ip::tcp::resolver> resolver =
make_shared<ip::tcp::resolver>(ref(getGlobalIoService()));
+ EventId connectTimeoutEvent = scheduler::schedule(timeout,
+ bind(&TcpChannel::handleFailedConnect, this,
+ clientSocket, onConnectFailed));
+
resolver->async_resolve(query,
bind(&TcpChannel::handleEndpointResolution, this, _1, _2,
- clientSocket, connectTimeoutTimer,
+ clientSocket, connectTimeoutEvent,
onFaceCreated, onConnectFailed,
resolver));
-
- connectTimeoutTimer->expires_from_now(timeout);
- connectTimeoutTimer->async_wait(bind(&TcpChannel::handleFailedConnect, this, _1,
- clientSocket, connectTimeoutTimer,
- onConnectFailed));
}
size_t
@@ -192,11 +184,11 @@
void
TcpChannel::handleSuccessfulConnect(const boost::system::error_code& error,
const shared_ptr<ip::tcp::socket>& socket,
- const shared_ptr<ndn::monotonic_deadline_timer>& timer,
+ const EventId& connectTimeoutEvent,
const FaceCreatedCallback& onFaceCreated,
const ConnectFailedCallback& onConnectFailed)
{
- timer->cancel();
+ scheduler::cancel(connectTimeoutEvent);
if (error) {
if (error == boost::system::errc::operation_canceled) // when socket is closed by someone
@@ -219,20 +211,11 @@
}
void
-TcpChannel::handleFailedConnect(const boost::system::error_code& error,
- const shared_ptr<ip::tcp::socket>& socket,
- const shared_ptr<ndn::monotonic_deadline_timer>& timer,
+TcpChannel::handleFailedConnect(const shared_ptr<ip::tcp::socket>& socket,
const ConnectFailedCallback& onConnectFailed)
{
- if (error) { // e.g., cancelled
- return;
- }
-
- NFD_LOG_DEBUG("Connect to remote endpoint timed out: "
- << error.category().message(error.value()));
-
- onConnectFailed("Connect to remote endpoint timed out: " +
- error.category().message(error.value()));
+ NFD_LOG_DEBUG("Connect to remote endpoint timed out");
+ onConnectFailed("Connect to remote endpoint timed out");
socket->close(); // abort the connection
}
@@ -240,7 +223,7 @@
TcpChannel::handleEndpointResolution(const boost::system::error_code& error,
ip::tcp::resolver::iterator remoteEndpoint,
const shared_ptr<boost::asio::ip::tcp::socket>& socket,
- const shared_ptr<ndn::monotonic_deadline_timer>& timer,
+ const EventId& connectTimeoutEvent,
const FaceCreatedCallback& onFaceCreated,
const ConnectFailedCallback& onConnectFailed,
const shared_ptr<ip::tcp::resolver>& resolver)
@@ -252,7 +235,7 @@
return;
socket->close();
- timer->cancel();
+ scheduler::cancel(connectTimeoutEvent);
NFD_LOG_DEBUG("Remote endpoint hostname or port cannot be resolved: "
<< error.category().message(error.value()));
@@ -265,7 +248,7 @@
// got endpoint, now trying to connect (only try the first resolution option)
socket->async_connect(*remoteEndpoint,
bind(&TcpChannel::handleSuccessfulConnect, this, _1,
- socket, timer,
+ socket, connectTimeoutEvent,
onFaceCreated, onConnectFailed));
}
diff --git a/daemon/face/tcp-channel.hpp b/daemon/face/tcp-channel.hpp
index c4f269c..f126a47 100644
--- a/daemon/face/tcp-channel.hpp
+++ b/daemon/face/tcp-channel.hpp
@@ -26,8 +26,8 @@
#define NFD_DAEMON_FACE_TCP_CHANNEL_HPP
#include "channel.hpp"
-#include <ndn-cxx/util/monotonic_deadline_timer.hpp>
#include "tcp-face.hpp"
+#include "core/scheduler.hpp"
namespace nfd {
@@ -124,21 +124,19 @@
void
handleSuccessfulConnect(const boost::system::error_code& error,
const shared_ptr<boost::asio::ip::tcp::socket>& socket,
- const shared_ptr<ndn::monotonic_deadline_timer>& timer,
+ const EventId& connectTimeoutEvent,
const FaceCreatedCallback& onFaceCreated,
const ConnectFailedCallback& onConnectFailed);
void
- handleFailedConnect(const boost::system::error_code& error,
- const shared_ptr<boost::asio::ip::tcp::socket>& socket,
- const shared_ptr<ndn::monotonic_deadline_timer>& timer,
+ handleFailedConnect(const shared_ptr<boost::asio::ip::tcp::socket>& socket,
const ConnectFailedCallback& onConnectFailed);
void
handleEndpointResolution(const boost::system::error_code& error,
boost::asio::ip::tcp::resolver::iterator remoteEndpoint,
const shared_ptr<boost::asio::ip::tcp::socket>& socket,
- const shared_ptr<ndn::monotonic_deadline_timer>& timer,
+ const EventId& connectTimeoutEvent,
const FaceCreatedCallback& onFaceCreated,
const ConnectFailedCallback& onConnectFailed,
const shared_ptr<boost::asio::ip::tcp::resolver>& resolver);
diff --git a/tests/daemon/face/tcp.cpp b/tests/daemon/face/tcp.cpp
index 0f64099..2861be3 100644
--- a/tests/daemon/face/tcp.cpp
+++ b/tests/daemon/face/tcp.cpp
@@ -566,6 +566,50 @@
"Exception thrown for " + Dataset::getName());
}
+class FaceCreateTimeoutFixture : protected BaseFixture
+{
+public:
+ void
+ onFaceCreated(const shared_ptr<Face>& newFace)
+ {
+ BOOST_CHECK_MESSAGE(false, "Timeout expected");
+ BOOST_CHECK(!static_cast<bool>(face1));
+ face1 = newFace;
+
+ limitedIo.afterOp();
+ }
+
+ void
+ onConnectFailed(const std::string& reason)
+ {
+ BOOST_CHECK_MESSAGE(true, reason);
+
+ limitedIo.afterOp();
+ }
+
+public:
+ LimitedIo limitedIo;
+
+ shared_ptr<Face> face1;
+};
+
+
+BOOST_FIXTURE_TEST_CASE(FaceCreateTimeout, FaceCreateTimeoutFixture)
+{
+ TcpFactory factory;
+ shared_ptr<TcpChannel> channel = factory.createChannel("0.0.0.0", "20070");
+
+ factory.createFace(FaceUri("tcp://192.0.2.1:20070"),
+ bind(&FaceCreateTimeoutFixture::onFaceCreated, this, _1),
+ bind(&FaceCreateTimeoutFixture::onConnectFailed, this, _1));
+
+ BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(10)) == LimitedIo::EXCEED_OPS,
+ "TcpChannel error: cannot connect or cannot accept connection");
+
+ BOOST_CHECK_EQUAL(static_cast<bool>(face1), false);
+}
+
+
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests