face: Reset io_service after io_service::poll()

In the case when after the io_service::poll call from the inside of
processEvents(<negative time>) there are no more handlers to dispatch,
io_service is moved to "stopped" state, which requires
io_service::reset() to be called in order for the future events to be
dispatched in subsequent poll/processEvents call.

Change-Id: I3dd4c44550a5cf6c6885f249ccfb7ba2fbf8198d
diff --git a/src/face.cpp b/src/face.cpp
index dece828..1db6371 100644
--- a/src/face.cpp
+++ b/src/face.cpp
@@ -367,6 +367,10 @@
 Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
                     bool keepThread/* = false*/)
 {
+  if (m_ioService.stopped()) {
+    m_ioService.reset(); // ensure that run()/poll() will do some work
+  }
+
   try {
     if (timeout < time::milliseconds::zero())
       {
@@ -387,16 +391,13 @@
     }
 
     m_ioService.run();
-    m_ioService.reset(); // so it is possible to run processEvents again (if necessary)
   }
   catch (Face::ProcessEventsTimeout&) {
     // break
     m_impl->m_ioServiceWork.reset();
-    m_ioService.reset();
   }
   catch (...) {
     m_impl->m_ioServiceWork.reset();
-    m_ioService.reset();
     m_impl->m_pendingInterestTable.clear();
     m_impl->m_registeredPrefixTable.clear();
     throw;
diff --git a/tests/unit-tests/test-faces.cpp b/tests/unit-tests/test-faces.cpp
index 3fcae2e..84982a0 100644
--- a/tests/unit-tests/test-faces.cpp
+++ b/tests/unit-tests/test-faces.cpp
@@ -367,6 +367,24 @@
   BOOST_CHECK_EQUAL(nInInterests, 2);
 }
 
+BOOST_AUTO_TEST_CASE(ProcessEvents)
+{
+  face->processEvents(time::milliseconds(-1)); // io_service::reset()/poll() inside
+
+  face->registerPrefix("/Hello/World",
+                       bind(&FacesFixture::onRegSucceeded, this),
+                       bind(&FacesFixture::onRegFailed, this));
+
+  // io_service::poll() without reset
+  face->getIoService().poll();
+  BOOST_CHECK_EQUAL(nRegFailures, 0);
+  BOOST_CHECK_EQUAL(nRegSuccesses, 0);
+
+  face->processEvents(time::milliseconds(-1)); // io_service::reset()/poll() inside
+  BOOST_CHECK_EQUAL(nRegFailures, 0);
+  BOOST_CHECK_EQUAL(nRegSuccesses, 1);
+}
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // tests