node: Ensure that processEvents blocks only if there are active events
Active events include:
- expressed Interests and awaiting for Data or Timeout
- set Interest filter
Change-Id: I75631ffca888a66ac7f31f38c7aa5fe204e2d510
diff --git a/include/ndn-cpp/node.hpp b/include/ndn-cpp/node.hpp
index b785be4..b28e91d 100644
--- a/include/ndn-cpp/node.hpp
+++ b/include/ndn-cpp/node.hpp
@@ -317,6 +317,7 @@
private:
ptr_lib::shared_ptr<boost::asio::io_service> ioService_;
ptr_lib::shared_ptr<boost::asio::deadline_timer> pitTimeoutCheckTimer_;
+ bool pitTimeoutCheckTimerActive_;
ptr_lib::shared_ptr<boost::asio::deadline_timer> processEventsTimeoutTimer_;
ptr_lib::shared_ptr<Transport> transport_;
diff --git a/src/node.cpp b/src/node.cpp
index 1ae1d3b..dcbcf84 100644
--- a/src/node.cpp
+++ b/src/node.cpp
@@ -29,27 +29,23 @@
uint64_t Node::RegisteredPrefix::lastRegisteredPrefixId_ = 0;
Node::Node(const ptr_lib::shared_ptr<Transport>& transport)
- : transport_(transport)
+ : pitTimeoutCheckTimerActive_(false)
+ , transport_(transport)
, ndndIdFetcherInterest_(Name("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY"), 4000.0)
{
ioService_ = ptr_lib::make_shared<boost::asio::io_service>();
pitTimeoutCheckTimer_ = ptr_lib::make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
processEventsTimeoutTimer_ = ptr_lib::make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
-
- pitTimeoutCheckTimer_->expires_from_now(boost::posix_time::milliseconds(100));
- pitTimeoutCheckTimer_->async_wait(func_lib::bind(&Node::checkPitExpire, this));
}
Node::Node(const ptr_lib::shared_ptr<Transport>& transport, const ptr_lib::shared_ptr<boost::asio::io_service> &ioService)
: ioService_(ioService)
+ , pitTimeoutCheckTimerActive_(false)
, transport_(transport)
, ndndIdFetcherInterest_(Name("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY"), 4000.0)
{
pitTimeoutCheckTimer_ = ptr_lib::make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
processEventsTimeoutTimer_ = ptr_lib::make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
-
- pitTimeoutCheckTimer_->expires_from_now(boost::posix_time::milliseconds(100));
- pitTimeoutCheckTimer_->async_wait(func_lib::bind(&Node::checkPitExpire, this));
}
uint64_t
@@ -64,6 +60,12 @@
(pendingInterestId, ptr_lib::shared_ptr<const Interest>(new Interest(interest)), onData, onTimeout)));
transport_->send(interest.wireEncode());
+
+ if (!pitTimeoutCheckTimerActive_) {
+ pitTimeoutCheckTimerActive_ = true;
+ pitTimeoutCheckTimer_->expires_from_now(boost::posix_time::milliseconds(100));
+ pitTimeoutCheckTimer_->async_wait(func_lib::bind(&Node::checkPitExpire, this));
+ }
return pendingInterestId;
}
@@ -264,8 +266,19 @@
}
}
- pitTimeoutCheckTimer_->expires_from_now(boost::posix_time::milliseconds(100));
- pitTimeoutCheckTimer_->async_wait(func_lib::bind(&Node::checkPitExpire, this));
+ if (!pendingInterestTable_.empty()) {
+ // pitTimeoutCheckTimerActive = true;
+ pitTimeoutCheckTimer_->expires_from_now(boost::posix_time::milliseconds(100));
+ pitTimeoutCheckTimer_->async_wait(func_lib::bind(&Node::checkPitExpire, this));
+ }
+ else {
+ pitTimeoutCheckTimerActive_ = false;
+
+ if (registeredPrefixTable_.empty()) {
+ transport_->close();
+ processEventsTimeoutTimer_->cancel();
+ }
+ }
}
@@ -302,7 +315,9 @@
Node::shutdown()
{
transport_->close();
- ioService_->stop();
+ pitTimeoutCheckTimer_->cancel();
+ processEventsTimeoutTimer_->cancel();
+ pitTimeoutCheckTimerActive_ = false;
}
Node::PendingInterestTable::iterator
diff --git a/src/transport/unix-transport.cpp b/src/transport/unix-transport.cpp
index 0463916..2704df1 100644
--- a/src/transport/unix-transport.cpp
+++ b/src/transport/unix-transport.cpp
@@ -110,6 +110,11 @@
if (error)
{
+ if (error == boost::system::errc::operation_canceled) {
+ // async receive has been explicitly cancelled (e.g., socket close)
+ return;
+ }
+
socket_.close(); // closing at this point may not be that necessary
transport_.isConnected_ = true;
throw Transport::Error(error, "error while receiving data from socket");