Serializing upcall/upcall final
diff --git a/ccnx/ccnx-closure.cpp b/ccnx/ccnx-closure.cpp
index 5abcb3e..ccfeafa 100644
--- a/ccnx/ccnx-closure.cpp
+++ b/ccnx/ccnx-closure.cpp
@@ -54,47 +54,61 @@
     }
 }
 
-ExecutorClosure::ExecutorClosure(const Closure &closure, ExecutorPtr executor)
-                : Closure(closure)
-                , m_executor(executor)
-{
-}
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-ExecutorClosure::~ExecutorClosure()
-{
-}
+// ExecutorClosure::ExecutorClosure(const Closure &closure, ExecutorPtr executor)
+//   : Closure(closure.m_dataCallback, closure.m_timeoutCallback)
+//   , m_executor(executor)
+// {
+// }
 
-void
-ExecutorClosure::runDataCallback(Name name, PcoPtr content)
-{
-  m_executor->execute(boost::bind(&ExecutorClosure::execute, this, name, content));
-}
+// ExecutorClosure::~ExecutorClosure()
+// {
+// }
 
-void
-ExecutorClosure::execute(Name name, PcoPtr content)
-{
-  Closure::runDataCallback(name, content);
-}
+// void
+// ExecutorClosure::runDataCallback(Name name, PcoPtr content)
+// {
+//   m_executor->execute(boost::bind(&Closure::runDataCallback, this, name, content));
+// }
 
-ExecutorInterestClosure::ExecutorInterestClosure(const InterestCallback &callback, ExecutorPtr executor)
-                        : m_callback(callback)
-                        , m_executor(executor)
-{
-}
+// // void
+// // ExecutorClosure::execute(Name name, PcoPtr content)
+// // {
+// //   Closure::runDataCallback(name, content);
+// // }
 
-void
-ExecutorInterestClosure::runInterestCallback(Name interest)
-{
-  m_executor->execute(boost::bind(&ExecutorInterestClosure::execute, this, interest));
-}
 
-void
-ExecutorInterestClosure::execute(Name interest)
-{
-  if (!m_callback.empty())
-  {
-    m_callback(interest);
-  }
-}
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+// ExecutorInterestClosure::ExecutorInterestClosure(const InterestCallback &callback, ExecutorPtr executor)
+//   : m_callback(callback)
+//   , m_executor(executor)
+// {
+// }
+
+// void
+// ExecutorInterestClosure::runInterestCallback(Name interest)
+// {
+//   m_executor->execute(boost::bind(&ExecutorInterestClosure::execute, this, interest));
+// }
+
+// void
+// ExecutorInterestClosure::execute(Name interest)
+// {
+//   if (!m_callback.empty())
+//   {
+//     m_callback(interest);
+//   }
+// }
 
 } // Ccnx
diff --git a/ccnx/ccnx-closure.h b/ccnx/ccnx-closure.h
index 8b80aa8..9741f6b 100644
--- a/ccnx/ccnx-closure.h
+++ b/ccnx/ccnx-closure.h
@@ -53,45 +53,48 @@
   virtual TimeoutCallbackReturnValue
   runTimeoutCallback(Name interest);
 
-protected:
+  virtual Closure *
+  dup () const { return new Closure (*this); }
+
+public:
   TimeoutCallback m_timeoutCallback;
   DataCallback m_dataCallback;
 };
 
-class ExecutorClosure : public Closure
-{
-public:
-  ExecutorClosure(const Closure &closure, ExecutorPtr executor);
-  virtual ~ExecutorClosure();
+// class ExecutorClosure : public Closure
+// {
+// public:
+//   ExecutorClosure(const Closure &closure, ExecutorPtr executor);
+//   virtual ~ExecutorClosure();
 
-  virtual void
-  runDataCallback(Name name, PcoPtr pco);
+//   virtual void
+//   runDataCallback(Name name, PcoPtr pco);
 
-private:
-  void
-  execute(Name nae, PcoPtr content);
+// // private:
+// //   void
+// //   execute(Name nae, PcoPtr content);
 
-private:
-  ExecutorPtr m_executor;
-};
+// private:
+//   ExecutorPtr m_executor;
+// };
 
-class ExecutorInterestClosure
-{
-public:
-  typedef boost::function<void (Name)> InterestCallback;
-  ExecutorInterestClosure(const InterestCallback &callback, ExecutorPtr executor);
-  ~ExecutorInterestClosure() {}
+// class ExecutorInterestClosure
+// {
+// public:
+//   typedef boost::function<void (Name)> InterestCallback;
+//   ExecutorInterestClosure(const InterestCallback &callback, ExecutorPtr executor);
+//   virtual ~ExecutorInterestClosure() {}
 
-  void
-  runInterestCallback(Name interest);
+//   void
+//   runInterestCallback(Name interest);
 
-  void
-  execute(Name interest);
+//   void
+//   execute(Name interest);
 
-private:
-  InterestCallback m_callback;
-  ExecutorPtr m_executor;
-};
+// private:
+//   InterestCallback m_callback;
+//   ExecutorPtr m_executor;
+// };
 
 } // Ccnx
 
diff --git a/ccnx/ccnx-wrapper.cpp b/ccnx/ccnx-wrapper.cpp
index 43c9780..0453789 100644
--- a/ccnx/ccnx-wrapper.cpp
+++ b/ccnx/ccnx-wrapper.cpp
@@ -245,18 +245,31 @@
 }
 
 
+static void
+deleterInInterestTuple (tuple<CcnxWrapper::InterestCallback *, ExecutorPtr> *tuple)
+{
+  delete tuple->get<0> ();
+  delete tuple;
+}
+
 static ccn_upcall_res
 incomingInterest(ccn_closure *selfp,
                  ccn_upcall_kind kind,
                  ccn_upcall_info *info)
 {
-  ExecutorInterestClosure *closure = static_cast<ExecutorInterestClosure*> (selfp->data);
+  CcnxWrapper::InterestCallback *f;
+  ExecutorPtr executor;
+  tuple<CcnxWrapper::InterestCallback *, ExecutorPtr> *realData = reinterpret_cast< tuple<CcnxWrapper::InterestCallback *, ExecutorPtr>* > (selfp->data);
+  tie (f, executor) = *realData;
+
   _LOG_TRACE (">> incomingInterest upcall");
 
   switch (kind)
     {
     case CCN_UPCALL_FINAL: // effective in unit tests
-      delete closure;
+      // delete closure;
+      executor->execute (bind (deleterInInterestTuple, realData));
+
       delete selfp;
       _LOG_TRACE ("<< incomingInterest with CCN_UPCALL_FINAL");
       return CCN_UPCALL_RESULT_OK;
@@ -271,25 +284,40 @@
 
   Name interest(info->interest_ccnb, info->interest_comps);
 
+  executor->execute (bind (*f, interest));
   // this will be run in executor
-  closure->runInterestCallback(interest);
+  // (*f) (interest);
+  // closure->runInterestCallback(interest);
 
   _LOG_TRACE ("<< incomingInterest");
   return CCN_UPCALL_RESULT_OK;
 }
 
+static void
+deleterInDataTuple (tuple<Closure *, ExecutorPtr> *tuple)
+{
+  delete tuple->get<0> ();
+  delete tuple;
+}
+
 static ccn_upcall_res
 incomingData(ccn_closure *selfp,
              ccn_upcall_kind kind,
              ccn_upcall_info *info)
 {
-  Closure *cp = static_cast<Closure *> (selfp->data);
+  // Closure *cp = static_cast<Closure *> (selfp->data);
+  Closure *cp;
+  ExecutorPtr executor;
+  tuple<Closure *, ExecutorPtr> *realData = reinterpret_cast< tuple<Closure*, ExecutorPtr>* > (selfp->data);
+  tie (cp, executor) = *realData;
+
   _LOG_TRACE (">> incomingData upcall");
 
   switch (kind)
     {
     case CCN_UPCALL_FINAL:  // effecitve in unit tests
-      delete cp;
+      executor->execute (bind (deleterInDataTuple, realData));
+
       cp = NULL;
       delete selfp;
       _LOG_TRACE ("<< incomingData with CCN_UPCALL_FINAL");
@@ -340,7 +368,8 @@
   // readRaw(content, pcontent, len);
 
   // this will be run in executor
-  cp->runDataCallback (pco->name (), pco);
+  executor->execute (bind (&Closure::runDataCallback, cp, pco->name (), pco));
+  // cp->runDataCallback (pco->name (), pco);
 
   _LOG_TRACE (">> incomingData");
 
@@ -363,8 +392,9 @@
   ccn_charbuf *pname = namePtr->getBuf();
   ccn_closure *dataClosure = new ccn_closure;
 
-  Closure *myClosure = new ExecutorClosure(closure, m_executor);
-  dataClosure->data = (void *)myClosure;
+  // Closure *myClosure = new ExecutorClosure(closure, m_executor);
+  Closure *myClosure = closure.dup ();
+  dataClosure->data = new tuple<Closure*, ExecutorPtr> (myClosure, m_executor);
 
   dataClosure->p = &incomingData;
 
@@ -399,7 +429,9 @@
   ccn_charbuf *pname = ptr->getBuf();
   ccn_closure *interestClosure = new ccn_closure;
 
-  interestClosure->data = new ExecutorInterestClosure(interestCallback, m_executor);
+  // interestClosure->data = new ExecutorInterestClosure(interestCallback, m_executor);
+
+  interestClosure->data = new tuple<CcnxWrapper::InterestCallback *, ExecutorPtr> (new InterestCallback (interestCallback), m_executor); // should be removed when closure is removed
   interestClosure->p = &incomingInterest;
 
   int ret = ccn_set_interest_filter (m_handle, pname, interestClosure);
@@ -409,7 +441,7 @@
   }
 
   m_registeredInterests.insert(pair<Name, InterestCallback>(prefix, interestCallback));
-  
+
   _LOG_TRACE ("<< setInterestFilter");
 
   return ret;