Merge branch 'master' of git.irl.cs.ucla.edu:ndn/sync
diff --git a/ccnx/sync-app-socket.cc b/ccnx/sync-app-socket.cc
index e0b76de..22d51b9 100644
--- a/ccnx/sync-app-socket.cc
+++ b/ccnx/sync-app-socket.cc
@@ -42,6 +42,14 @@
   CcnxWrapper::Destroy ();
 }
 
+std::string
+SyncAppSocket::GetLocalPrefix()
+{
+  // this handle is supposed to be short lived
+  CcnxWrapperPtr handle = CcnxWrapper::Create();
+  return handle->getLocalPrefix();
+}
+
 bool 
 SyncAppSocket::publishString (const string &prefix, uint32_t session, const string &dataBuffer, int freshness)
 {
diff --git a/include/sync-app-socket.h b/include/sync-app-socket.h
index a878c9d..ceeb5ce 100644
--- a/include/sync-app-socket.h
+++ b/include/sync-app-socket.h
@@ -90,8 +90,10 @@
   SyncLogic &
   getLogic () { return m_syncLogic; }
 
-  std::string
-  getLocalPrefix () { return m_ccnxHandle->getLocalPrefix (); }
+  // make this a static function so we don't have to create socket instance without
+  // knowing the local prefix. it's a wrong place for this function anyway
+  static std::string
+  GetLocalPrefix (); 
   
 private:
   void 
diff --git a/include/sync-logic.h b/include/sync-logic.h
index 7daede2..ef63267 100644
--- a/include/sync-logic.h
+++ b/include/sync-logic.h
@@ -170,6 +170,10 @@
   sendSyncData (const std::string &name,
                 DigestConstPtr digest, StateConstPtr state);
 
+  void
+  sendSyncData (const std::string &name,
+                DigestConstPtr digest, SyncStateMsg &msg);
+
   size_t
   getNumberOfBranches () const;
   
diff --git a/model/sync-logic.cc b/model/sync-logic.cc
index a060b0f..f298768 100644
--- a/model/sync-logic.cc
+++ b/model/sync-logic.cc
@@ -247,16 +247,26 @@
 void
 SyncLogic::processSyncInterest (const std::string &name, DigestConstPtr digest, bool timedProcessing/*=false*/)
 {
-  recursive_mutex::scoped_lock lock (m_stateMutex);
+  DigestConstPtr rootDigest;
+  {
+    recursive_mutex::scoped_lock lock (m_stateMutex);
+    rootDigest = m_state->getDigest();
+  }
 
   // Special case when state is not empty and we have received request with zero-root digest
-  if (digest->isZero () && !m_state->getDigest()->isZero ())
+  if (digest->isZero () && !rootDigest->isZero ())
     {
-      sendSyncData (name, digest, m_state);
+      
+      SyncStateMsg ssm;
+      {
+        recursive_mutex::scoped_lock lock (m_stateMutex);
+        ssm << (*m_state);
+      }
+      sendSyncData (name, digest, ssm);
       return;
     }
 
-  if (*m_state->getDigest() == *digest)
+  if (*rootDigest == *digest)
     {
       _LOG_TRACE ("processSyncInterest (): Same state. Adding to PIT");
       m_syncInterestTable.insert (digest, name, false);
@@ -306,7 +316,6 @@
   
   try
     {
-      recursive_mutex::scoped_lock lock (m_stateMutex);
 
       m_syncInterestTable.remove (name); // Remove satisfied interest from PIT
 
@@ -335,7 +344,10 @@
               bool inserted = false;
               bool updated = false;
               SeqNo oldSeq;
-              tie (inserted, updated, oldSeq) = m_state->update (info, seq);
+              {
+                recursive_mutex::scoped_lock lock (m_stateMutex);
+                tie (inserted, updated, oldSeq) = m_state->update (info, seq);
+              }
 
               if (inserted || updated)
                 {
@@ -367,6 +379,7 @@
             }
           else if (diffLeaf->getOperation() == REMOVE)
             {
+              recursive_mutex::scoped_lock lock (m_stateMutex);
               if (m_state->remove (info))
                 {
                   diffLog->remove (info);
@@ -418,7 +431,6 @@
 void
 SyncLogic::processSyncRecoveryInterest (const std::string &name, DigestConstPtr digest)
 {
-  recursive_mutex::scoped_lock lock (m_stateMutex);
   
   DiffStateContainer::iterator stateInDiffLog = m_log.find (digest);
 
@@ -428,7 +440,12 @@
       return;
     }
 
-  sendSyncData (name, digest, m_state);
+  SyncStateMsg ssm;
+  {
+    recursive_mutex::scoped_lock lock (m_stateMutex);
+    ssm << (*m_state);
+  }
+  sendSyncData (name, digest, ssm);
 }
 
 void
@@ -588,10 +605,17 @@
 void
 SyncLogic::sendSyncData (const std::string &name, DigestConstPtr digest, StateConstPtr state)
 {
+  SyncStateMsg msg;
+  msg << (*state);
+  sendSyncData(name, digest, msg);
+}
+
+// pass in state msg instead of state, so that there is no need to lock the state until
+// this function returns
+void
+SyncLogic::sendSyncData (const std::string &name, DigestConstPtr digest, SyncStateMsg &ssm)
+{
   _LOG_TRACE (">> D " << name);
-  // sending
-  SyncStateMsg ssm;
-  ssm << (*state);
   int size = ssm.ByteSize();
   char *wireData = new char[size];
   ssm.SerializeToArray(wireData, size);