allow UpdateRepos to busy wait, and use this instead of CRepositoryUpdateJob::GrabAdd...
authorJonathan Marshall <jmarshall@never.you.mind>
Mon, 14 Mar 2011 00:44:54 +0000 (13:44 +1300)
committerJonathan Marshall <jmarshall@never.you.mind>
Wed, 16 Mar 2011 20:25:54 +0000 (09:25 +1300)
xbmc/addons/AddonInstaller.cpp
xbmc/addons/AddonInstaller.h
xbmc/filesystem/AddonsDirectory.cpp

index 537ca17..b3e67f9 100644 (file)
@@ -69,6 +69,7 @@ void CAddonInstaller::OnJobComplete(unsigned int jobID, bool success, CJob* job)
   CSingleLock lock(m_critSection);
   if (strncmp(job->GetType(), "repoupdate", 10) == 0)
   { // repo job finished
+    m_repoUpdateDone.Set();
     m_repoUpdateJob = 0;
   }
   else
@@ -247,19 +248,9 @@ bool CAddonInstaller::InstallFromZip(const CStdString &path)
 
 void CAddonInstaller::InstallFromXBMCRepo(const set<CStdString> &addonIDs)
 {
-  // first check we have the main repository updated...
-  AddonPtr addon;
-  if (CAddonMgr::Get().GetAddon("repository.xbmc.org", addon))
-  {
-    VECADDONS addons;
-    CAddonDatabase database;
-    database.Open();
-    if (!database.GetRepository(addon->ID(), addons))
-    {
-      RepositoryPtr repo = boost::dynamic_pointer_cast<CRepository>(addon);
-      addons = CRepositoryUpdateJob::GrabAddons(repo, false);
-    }
-  }
+  // first check we have the our repositories up to date (and wait until we do)
+  UpdateRepos(false, true);
+
   // now install the addons
   for (set<CStdString>::const_iterator i = addonIDs.begin(); i != addonIDs.end(); ++i)
     Install(*i);
@@ -297,9 +288,17 @@ bool CAddonInstaller::CheckDependencies(const AddonPtr &addon)
 void CAddonInstaller::UpdateRepos(bool force, bool wait)
 {
   CSingleLock lock(m_critSection);
-  if (!force && m_repoUpdateWatch.IsRunning() && m_repoUpdateWatch.GetElapsedSeconds() < 600)
-    return;
   if (m_repoUpdateJob)
+  {
+    if (wait)
+    { // wait for our job to complete
+      lock.Leave();
+      CLog::Log(LOGDEBUG, "%s - waiting for repository update job to finish...", __FUNCTION__);
+      m_repoUpdateDone.Wait();
+    }
+    return;
+  }
+  if (!force && m_repoUpdateWatch.IsRunning() && m_repoUpdateWatch.GetElapsedSeconds() < 600)
     return;
   m_repoUpdateWatch.StartZero();
   VECADDONS addons;
@@ -313,6 +312,12 @@ void CAddonInstaller::UpdateRepos(bool force, bool wait)
     {
       CLog::Log(LOGDEBUG,"Checking repositories for updates (triggered by %s)",addons[i]->Name().c_str());
       m_repoUpdateJob = CJobManager::GetInstance().AddJob(new CRepositoryUpdateJob(addons), this);
+      if (wait)
+      { // wait for our job to complete
+        lock.Leave();
+        CLog::Log(LOGDEBUG, "%s - waiting for this repository update job to finish...", __FUNCTION__);
+        m_repoUpdateDone.Wait();
+      }
       return;
     }
   }
index 0671a25..d3305bf 100644 (file)
@@ -23,6 +23,7 @@
 #include "utils/FileOperationJob.h"
 #include "addons/IAddon.h"
 #include "utils/Stopwatch.h"
+#include "threads/Event.h"
 
 class CAddonInstaller : public IJobCallback
 {
@@ -66,10 +67,12 @@ public:
 
   /*! \brief Update all repositories (if needed)
    Runs through all available repositories and queues an update of them if they
-   need it (according to the set timeouts) or if forced.
+   need it (according to the set timeouts) or if forced.  Optionally busy wait
+   until the repository updates are complete.
    \param force whether we should run an update regardless of the normal update cycle. Defaults to false.
+   \param wait whether we should busy wait for the updates to be performed. Defaults to false.
    */
-  void UpdateRepos(bool force = false);
+  void UpdateRepos(bool force = false, bool wait = false);
 
   void OnJobComplete(unsigned int jobID, bool success, CJob* job);
   void OnJobProgress(unsigned int jobID, unsigned int progress, unsigned int total, const CJob *job);
@@ -109,6 +112,7 @@ private:
   JobMap m_downloadJobs;
   CStopWatch m_repoUpdateWatch;   ///< repository updates are done based on this counter
   unsigned int m_repoUpdateJob;   ///< the job ID of the repository updates
+  CEvent m_repoUpdateDone;        ///< event set when the repository updates are complete
 };
 
 class CAddonInstallJob : public CFileOperationJob
index 0fc364a..2080fdb 100644 (file)
@@ -27,6 +27,7 @@
 #include "DirectoryCache.h"
 #include "FileItem.h"
 #include "addons/Repository.h"
+#include "addons/AddonInstaller.h"
 #include "addons/PluginSource.h"
 #include "guilib/TextureManager.h"
 #include "File.h"
@@ -96,13 +97,12 @@ bool CAddonsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &it
     CAddonMgr::Get().GetAddon(path.GetHostName(),addon);
     if (!addon)
       return false;
+
+    // ensure our repos are up to date
+    CAddonInstaller::Get().UpdateRepos(false, true);
     CAddonDatabase database;
     database.Open();
-    if (!database.GetRepository(addon->ID(),addons))
-    {
-      RepositoryPtr repo = boost::dynamic_pointer_cast<CRepository>(addon);
-      addons = CRepositoryUpdateJob::GrabAddons(repo,false);
-    }
+    database.GetRepository(addon->ID(),addons);
     items.SetProperty("reponame",addon->Name());
   }