]> git.mxchange.org Git - simgear.git/commitdiff
Allow TerraSync to be inited early.
authorJames Turner <zakalawe@mac.com>
Thu, 26 Sep 2013 11:11:48 +0000 (12:11 +0100)
committerJames Turner <zakalawe@mac.com>
Thu, 26 Sep 2013 11:11:48 +0000 (12:11 +0100)
Add explicit subsystem state tracking so we can safely init()
terrasync very early during startup, and hence overlap lengthy operations
(Shared Models sync and initial NavCache build)

simgear/scene/tsync/terrasync.cxx
simgear/scene/tsync/terrasync.hxx

index bf25d207652b701ee88658b00451c55dfb2d75fa..fae3cf503a96f7206ec81b033ec0bb7bcc1692ac 100644 (file)
@@ -152,11 +152,17 @@ public:
 class SyncSlot
 {
 public:
+    SyncSlot() :
+        isNewDirectory(false),
+        busy(false)
+    {}
+    
     WaitingSyncItem currentItem;
     bool isNewDirectory;
     std::queue<WaitingSyncItem> queue;
     std::auto_ptr<SVNRepository> repository;
     SGTimeStamp stamp;
+    bool busy; ///< is the slot working or idle
 };
 
 static const int SYNC_SLOT_TILES = 0; ///< Terrain and Objects sync
@@ -499,10 +505,12 @@ void SGTerraSync::SvnThread::syncPathExternal(const WaitingSyncItem& next)
         }
     } catch (sg_exception& e) {
         fail(next);
+        _busy = false;
         return;
     }
     
     updated(next, isNewDirectory);
+    _busy = false;
 }
 
 void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
@@ -526,6 +534,7 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
         }
 
         // whatever happened, we're done with this repository instance
+        slot.busy = false;
         slot.repository.reset();
     }
     
@@ -552,6 +561,7 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
         slot.repository->update();
         
         slot.stamp.stamp();
+        slot.busy = true;
         SG_LOG(SG_IO, SG_DEBUG, "sync of " << slot.repository->baseUrl() << " started");
     }
 }
@@ -577,10 +587,14 @@ void SGTerraSync::SvnThread::runInternal()
             _syncSlots[slot].queue.push(next);
         }
        
+        bool anySlotBusy = false;
         // update each sync slot in turn
         for (unsigned int slot=0; slot < NUM_SYNC_SLOTS; ++slot) {
             updateSyncSlot(_syncSlots[slot]);
+            anySlotBusy |= _syncSlots[slot].busy;
         }
+        
+        _busy = anySlotBusy;
     } // of thread running loop
 }
 
@@ -608,7 +622,6 @@ void SGTerraSync::SvnThread::fail(const WaitingSyncItem& failedItem)
     _consecutive_errors++;
     _fail_count++;
     _completedTiles[ failedItem._dir ] = now + UpdateInterval::FailedAttempt;
-    _busy = false;
 }
 
 void SGTerraSync::SvnThread::updated(const WaitingSyncItem& item, bool isNewDirectory)
@@ -632,7 +645,6 @@ void SGTerraSync::SvnThread::updated(const WaitingSyncItem& item, bool isNewDire
     
     _completedTiles[ item._dir ] = now + UpdateInterval::SuccessfulAttempt;
     writeCompletedTilesPersistentCache();
-    _busy = false;
 }
 
 void SGTerraSync::SvnThread::initCompletedTilesPersistentCache()
@@ -689,6 +701,8 @@ SGTerraSync::SGTerraSync(SGPropertyNode_ptr root) :
     last_lat(NOWHERE),
     last_lon(NOWHERE),
     _terraRoot(root->getNode("/sim/terrasync",true)),
+    _bound(false),
+    _inited(false),
     _refreshCb(NULL),
     _userCbData(NULL)
 {
@@ -710,6 +724,11 @@ SGTerraSync::~SGTerraSync()
 
 void SGTerraSync::init()
 {
+    if (_inited) {
+        return;
+    }
+    
+    _inited = true;
     _refreshDisplay = _terraRoot->getNode("refresh-display",true);
     _terraRoot->setBoolValue("built-in-svn-available",svn_built_in_available);
     reinit();
@@ -720,8 +739,10 @@ void SGTerraSync::reinit()
     // do not reinit when enabled and we're already up and running
     if ((_terraRoot->getBoolValue("enabled",false))&&
          (_svnThread->_active && _svnThread->_running))
+    {
         return;
-
+    }
+    
     _svnThread->stop();
 
     if (_terraRoot->getBoolValue("enabled",false))
@@ -756,6 +777,11 @@ void SGTerraSync::reinit()
 
 void SGTerraSync::bind()
 {
+    if (_bound) {
+        return;
+    }
+    
+    _bound = true;
     _tiedProperties.Tie( _terraRoot->getNode("busy", true), (bool*) &_svnThread->_busy );
     _tiedProperties.Tie( _terraRoot->getNode("active", true), (bool*) &_svnThread->_active );
     _tiedProperties.Tie( _terraRoot->getNode("update-count", true), (int*) &_svnThread->_success_count );
@@ -780,6 +806,8 @@ void SGTerraSync::unbind()
 {
     _svnThread->stop();
     _tiedProperties.Untie();
+    _bound = false;
+    _inited = false;
 }
 
 void SGTerraSync::update(double)
index 0ba4bed6796cd08b77a0694e4b93e696bfd3dcca..3e0db27d66bd36c5e5510c6d176868e8466c55d9 100644 (file)
@@ -42,7 +42,8 @@ public:
 
     SGTerraSync(SGPropertyNode_ptr root);
     virtual ~SGTerraSync();
-    virtual void init();
+    
+    virtual void init();    
     virtual void reinit();
     virtual void bind();
     virtual void unbind();
@@ -76,6 +77,12 @@ private:
     SGPropertyNode_ptr _stalledNode;
     SGPropertyNode_ptr _cacheHits;
     
+    // we manually bind+init TerraSync during early startup
+    // to get better overlap of slow operations (Shared Models sync
+    // and nav-cache rebuild). As a result we need to track the bind/init
+    // state explicitly to avoid duplicate calls.
+    bool _bound, _inited;
+    
     SGTerraSyncCallback _refreshCb;
     void* _userCbData;
     simgear::TiedPropertyList _tiedProperties;