face: use post instead of dispatch to avoid re-entrancy issues

This fixes a segfault in satisfyPendingInterests when Face::put is
called in DataCallback. Other functions are also safeguarded
against similar situations.

refs: #4596

Change-Id: I8d1564b0d28d1ee7b80c50712d888f874804823a
diff --git a/tests/unit-tests/face.t.cpp b/tests/unit-tests/face.t.cpp
index e731c68..2412c66 100644
--- a/tests/unit-tests/face.t.cpp
+++ b/tests/unit-tests/face.t.cpp
@@ -299,6 +299,23 @@
   BOOST_CHECK(true);
 }
 
+BOOST_AUTO_TEST_CASE(DataCallbackPutData) // Bug 4596
+{
+  face.expressInterest(Interest("/localhost/notification/1"),
+                       [&] (const Interest& i, const Data& d) {
+                         face.put(*makeData("/chronosync/sampleDigest/1"));
+                       }, nullptr, nullptr);
+  advanceClocks(10_ms);
+  BOOST_CHECK_EQUAL(face.sentInterests.back().getName(), "/localhost/notification/1");
+
+  face.receive(Interest("/chronosync/sampleDigest"));
+  advanceClocks(10_ms);
+
+  face.put(*makeData("/localhost/notification/1"));
+  advanceClocks(10_ms);
+  BOOST_CHECK_EQUAL(face.sentData.back().getName(), "/chronosync/sampleDigest/1");
+}
+
 BOOST_AUTO_TEST_SUITE_END() // Consumer
 
 BOOST_AUTO_TEST_SUITE(Producer)