ping: Code refactoring
Change-Id: I8b4e2c9dd3ba3adfae8d296a5635b048b35cf593
Refs: #3137
diff --git a/tools/ping/client/ndn-ping.cpp b/tools/ping/client/ndn-ping.cpp
index a26b1b1..d94cd0c 100644
--- a/tools/ping/client/ndn-ping.cpp
+++ b/tools/ping/client/ndn-ping.cpp
@@ -31,6 +31,89 @@
namespace ping {
namespace client {
+class Runner : noncopyable
+{
+public:
+ explicit
+ Runner(const Options& options)
+ : m_ping(m_face, options)
+ , m_statisticsCollector(m_ping, options)
+ , m_tracer(m_ping, options)
+ , m_signalSetInt(m_face.getIoService(), SIGINT)
+ , m_signalSetQuit(m_face.getIoService(), SIGQUIT)
+ {
+ m_signalSetInt.async_wait(bind(&Runner::afterIntSignal, this, _1));
+ m_signalSetQuit.async_wait(bind(&Runner::afterQuitSignal, this, _1));
+
+ m_ping.afterFinish.connect([this] {
+ this->cancel();
+ });
+ }
+
+ int
+ run()
+ {
+ try {
+ m_ping.start();
+ m_face.processEvents();
+ }
+ catch (std::exception& e) {
+ m_tracer.onError(e.what());
+ return 2;
+ }
+
+ Statistics statistics = m_statisticsCollector.computeStatistics();
+
+ std::cout << statistics << std::endl;
+
+ if (statistics.nReceived == statistics.nSent) {
+ return 0;
+ }
+ else {
+ return 1;
+ }
+ }
+
+private:
+ void
+ cancel()
+ {
+ m_signalSetInt.cancel();
+ m_signalSetQuit.cancel();
+ m_ping.stop();
+ }
+
+ void
+ afterIntSignal(const boost::system::error_code& errorCode)
+ {
+ if (errorCode == boost::asio::error::operation_aborted) {
+ return;
+ }
+
+ cancel();
+ }
+
+ void
+ afterQuitSignal(const boost::system::error_code& errorCode)
+ {
+ if (errorCode == boost::asio::error::operation_aborted) {
+ return;
+ }
+
+ m_statisticsCollector.computeStatistics().printSummary(std::cout);
+ m_signalSetQuit.async_wait(bind(&Runner::afterQuitSignal, this, _1));
+ };
+
+private:
+ Face m_face;
+ Ping m_ping;
+ StatisticsCollector m_statisticsCollector;
+ Tracer m_tracer;
+
+ boost::asio::signal_set m_signalSetInt;
+ boost::asio::signal_set m_signalSetQuit;
+};
+
static time::milliseconds
getMinimumPingInterval()
{
@@ -61,34 +144,6 @@
exit(2);
}
-/**
- * @brief SIGINT handler: print statistics and exit
- */
-static void
-onSigInt(Face& face, StatisticsCollector& statisticsCollector)
-{
- face.shutdown();
- Statistics statistics = statisticsCollector.computeStatistics();
- std::cout << statistics << std::endl;
-
- if (statistics.nReceived == statistics.nSent) {
- exit(0);
- }
- else {
- exit(1);
- }
-}
-
-/**
- * @brief SIGQUIT handler: print statistics summary and continue
- */
-static void
-onSigQuit(StatisticsCollector& statisticsCollector, boost::asio::signal_set& signalSet)
-{
- statisticsCollector.computeStatistics().printSummary(std::cout);
- signalSet.async_wait(bind(&onSigQuit, ref(statisticsCollector), ref(signalSet)));
-}
-
int
main(int argc, char* argv[])
{
@@ -205,39 +260,8 @@
usage(visibleOptDesc);
}
- boost::asio::io_service ioService;
- Face face(ioService);
- Ping ping(face, options);
- StatisticsCollector statisticsCollector(ping, options);
- Tracer tracer(ping, options);
-
- boost::asio::signal_set signalSetInt(face.getIoService(), SIGINT);
- signalSetInt.async_wait(bind(&onSigInt, ref(face), ref(statisticsCollector)));
-
- boost::asio::signal_set signalSetQuit(face.getIoService(), SIGQUIT);
- signalSetQuit.async_wait(bind(&onSigQuit, ref(statisticsCollector), ref(signalSetQuit)));
-
std::cout << "PING " << options.prefix << std::endl;
-
- try {
- ping.run();
- }
- catch (std::exception& e) {
- tracer.onError(e.what());
- face.getIoService().stop();
- return 2;
- }
-
- Statistics statistics = statisticsCollector.computeStatistics();
-
- std::cout << statistics << std::endl;
-
- if (statistics.nReceived == statistics.nSent) {
- return 0;
- }
- else {
- return 1;
- }
+ return Runner(options).run();
}
} // namespace client
diff --git a/tools/ping/client/ping.cpp b/tools/ping/client/ping.cpp
index 8f1ba98..b60be65 100644
--- a/tools/ping/client/ping.cpp
+++ b/tools/ping/client/ping.cpp
@@ -33,6 +33,7 @@
, m_nOutstanding(0)
, m_face(face)
, m_scheduler(m_face.getIoService())
+ , m_nextPingEvent(m_scheduler)
{
if (m_options.shouldGenerateRandomSeq) {
m_nextSeq = random::generateWord64();
@@ -40,20 +41,18 @@
}
void
-Ping::run()
-{
- start();
-
- m_face.getIoService().run();
-}
-
-void
Ping::start()
{
performPing();
}
void
+Ping::stop()
+{
+ m_nextPingEvent.cancel();
+}
+
+void
Ping::performPing()
{
BOOST_ASSERT((m_options.nPings < 0) || (m_nSent < m_options.nPings));
@@ -73,7 +72,7 @@
++m_nOutstanding;
if ((m_options.nPings < 0) || (m_nSent < m_options.nPings)) {
- m_scheduler.scheduleEvent(m_options.interval, bind(&Ping::performPing, this));
+ m_nextPingEvent = m_scheduler.scheduleEvent(m_options.interval, bind(&Ping::performPing, this));
}
else {
finish();
@@ -105,9 +104,7 @@
return;
}
- m_face.shutdown();
afterFinish();
- m_face.getIoService().stop();
}
Name
diff --git a/tools/ping/client/ping.hpp b/tools/ping/client/ping.hpp
index 3f99fd7..49ac492 100644
--- a/tools/ping/client/ping.hpp
+++ b/tools/ping/client/ping.hpp
@@ -56,51 +56,61 @@
Ping(Face& face, const Options& options);
/**
- * Signals on the successful return of a packet
+ * @brief Signals on the successful return of a packet
+ *
* @param seq ping sequence number
* @param rtt round trip time
*/
signal::Signal<Ping, uint64_t, Rtt> afterResponse;
/**
- * Signals on timeout of a packet
+ * @brief Signals on timeout of a packet
+ *
* @param seq ping sequence number
*/
signal::Signal<Ping, uint64_t> afterTimeout;
/**
- * Signals when finished pinging
+ * @brief Signals when finished pinging
*/
signal::Signal<Ping> afterFinish;
/**
- * Runs the ping client (blocking)
- */
- void
- run();
-
- /**
- * Runs the ping client (non-blocking)
+ * @brief Start sending ping interests
+ *
+ * @note This method is non-blocking and caller need to call face.processEvents()
*/
void
start();
+ /**
+ * @brief Stop sending ping interests
+ *
+ * This method cancels any future ping interests and does not affect already pending interests.
+ *
+ * @todo Cancel pending ping interest
+ */
+ void
+ stop();
+
private:
/**
- * Creates a ping Name from the sequence number
+ * @brief Creates a ping Name from the sequence number
+ *
* @param seq ping sequence number
*/
Name
makePingName(uint64_t seq) const;
/**
- * Performs individual ping
+ * @brief Performs individual ping
*/
void
performPing();
/**
- * Called when ping returned successfully
+ * @brief Called when ping returned successfully
+ *
* @param interest NDN interest
* @param data returned data
* @param seq ping sequence number
@@ -110,7 +120,8 @@
onData(const Interest& interest, Data& data, uint64_t seq, const time::steady_clock::TimePoint& sendTime);
/**
- * Called when ping timed out
+ * @brief Called when ping timed out
+ *
* @param interest NDN interest
* @param seq ping sequence number
*/
@@ -118,7 +129,7 @@
onTimeout(const Interest& interest, uint64_t seq);
/**
- * Called after ping received or timed out
+ * @brief Called after ping received or timed out
*/
void
finish();
@@ -130,6 +141,7 @@
int m_nOutstanding;
Face& m_face;
scheduler::Scheduler m_scheduler;
+ scheduler::ScopedEventId m_nextPingEvent;
};
} // namespace client
diff --git a/tools/ping/client/statistics-collector.hpp b/tools/ping/client/statistics-collector.hpp
index 76278db..2ced820 100644
--- a/tools/ping/client/statistics-collector.hpp
+++ b/tools/ping/client/statistics-collector.hpp
@@ -52,7 +52,7 @@
};
/**
- * @brief collects statistics from ping client
+ * @brief Statistics collector from ping client
*/
class StatisticsCollector : noncopyable
{
@@ -64,21 +64,22 @@
StatisticsCollector(Ping& ping, const Options& options);
/**
- * Returns ping statistics as structure
+ * @brief Compute ping statistics as structure
*/
Statistics
computeStatistics();
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/**
- * Called on ping response received
+ * @brief Called on ping response received
+ *
* @param rtt round trip time
*/
void
recordResponse(Rtt rtt);
/**
- * Called on ping timeout
+ * @brief Called on ping timeout
*/
void
recordTimeout();
diff --git a/tools/ping/client/tracer.hpp b/tools/ping/client/tracer.hpp
index 5a8cd35..f62b9b8 100644
--- a/tools/ping/client/tracer.hpp
+++ b/tools/ping/client/tracer.hpp
@@ -43,7 +43,8 @@
Tracer(Ping& ping, const Options& options);
/**
- * Prints ping results when response received
+ * @brief Prints ping results when response received
+ *
* @param seq ping sequence number
* @param rtt round trip time
*/
@@ -51,14 +52,15 @@
onResponse(uint64_t seq, Rtt rtt);
/**
- * Prints ping results when timed out
+ * @brief Prints ping results when timed out
+ *
* @param seq ping sequence number
*/
void
onTimeout(uint64_t seq);
/**
- * Outputs ping errors to cerr
+ * @brief Outputs ping errors to cerr
*/
void
onError(std::string msg);