timed-wait for fetcher in hope to solve crash problem

Change-Id: I43d975c79deae25ab193fa484127b246e917724f
diff --git a/src/fetch-manager.cc b/src/fetch-manager.cc
index d152c30..1949518 100644
--- a/src/fetch-manager.cc
+++ b/src/fetch-manager.cc
@@ -23,6 +23,7 @@
 #include <boost/make_shared.hpp>
 #include <boost/ref.hpp>
 #include <boost/throw_exception.hpp>
+#include <boost/lexical_cast.hpp>
 
 #include "simple-interval-generator.h"
 #include "logging.h"
@@ -157,6 +158,12 @@
           continue;
         }
 
+      if (item->IsTimedWait ())
+        {
+          _LOG_DEBUG ("Item is in timed-wait");
+          continue;
+        }
+
       if (currentTime < item->GetNextScheduledRetry ())
         {
           if (item->GetNextScheduledRetry () < nextSheduleCheck)
@@ -223,8 +230,6 @@
   {
     unique_lock<mutex> lock (m_parellelFetchMutex);
     m_currentParallelFetches --;
-    _LOG_TRACE ("+++++ removing fetcher: " << fetcher.GetName ());
-    m_fetchList.erase_and_dispose (FetchList::s_iterator_to (fetcher), fetcher_disposer ());
 
     if (m_taskDb)
       {
@@ -232,5 +237,16 @@
       }
   }
 
+  // like TCP timed-wait
+  m_scheduler->scheduleOneTimeTask(m_scheduler, 10, boost::bind(&FetchManager::TimedWait, this, ref(fetcher)), boost::lexical_cast<string>(baseName));
+
   m_scheduler->rescheduleTaskAt (m_scheduleFetchesTask, 0);
 }
+
+void
+FetchManager::TimedWait (Fetcher &fetcher)
+{
+    unique_lock<mutex> lock (m_parellelFetchMutex);
+    _LOG_TRACE ("+++++ removing fetcher: " << fetcher.GetName ());
+    m_fetchList.erase_and_dispose (FetchList::s_iterator_to (fetcher), fetcher_disposer ());
+}
diff --git a/src/fetch-manager.h b/src/fetch-manager.h
index 31cb063..25ccac0 100644
--- a/src/fetch-manager.h
+++ b/src/fetch-manager.h
@@ -85,6 +85,9 @@
   void
   ScheduleFetches ();
 
+  void
+  TimedWait (Fetcher &fetcher);
+
 private:
   Ccnx::CcnxWrapperPtr m_ccnx;
   Mapping m_mapping;
diff --git a/src/fetcher.cc b/src/fetcher.cc
index 3334040..be9064a 100644
--- a/src/fetcher.cc
+++ b/src/fetcher.cc
@@ -51,6 +51,7 @@
   , m_finishCallback (finishCallback)
 
   , m_active (false)
+  , m_timedwait (false)
   , m_name (name)
   , m_deviceName (deviceName)
   , m_forwardingHint (forwardingHint)
@@ -201,6 +202,7 @@
       // using executor, so we won't be deleted if there is scheduled FillPipeline call
       if (!m_onFetchComplete.empty ())
         {
+          m_timedwait = true;
           m_executor->execute (bind (m_onFetchComplete, ref(*this), m_deviceName, m_name));
         }
     }
diff --git a/src/fetcher.h b/src/fetcher.h
index 41a2301..0a0fe9d 100644
--- a/src/fetcher.h
+++ b/src/fetcher.h
@@ -53,6 +53,9 @@
   inline bool
   IsActive () const;
 
+  inline bool
+  IsTimedWait() const { return m_timedwait; }
+
   void
   RestartPipeline ();
 
@@ -109,6 +112,7 @@
   FinishCallback m_finishCallback;
 
   bool m_active;
+  bool m_timedwait;
 
   Ccnx::Name m_name;
   Ccnx::Name m_deviceName;