/*
* Copyright (C) 2005-2013 Team XBMC
- * http://www.xbmc.org
+ * http://xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
using namespace std;
-#define ITEMS_PER_THREAD 5
-
-CBackgroundInfoLoader::CBackgroundInfoLoader(int nThreads)
+CBackgroundInfoLoader::CBackgroundInfoLoader() : m_thread (NULL)
{
m_bStop = true;
m_pObserver=NULL;
m_pProgressCallback=NULL;
m_pVecItems = NULL;
- m_nRequestedThreads = nThreads;
- m_bStartCalled = false;
- m_nActiveThreads = 0;
+ m_bIsLoading = false;
}
CBackgroundInfoLoader::~CBackgroundInfoLoader()
StopThread();
}
-void CBackgroundInfoLoader::SetNumOfWorkers(int nThreads)
-{
- m_nRequestedThreads = nThreads;
-}
-
void CBackgroundInfoLoader::Run()
{
try
{
if (m_vecItems.size() > 0)
{
+ OnLoaderStart();
+
+ // Stage 1: All "fast" stuff we have already cached
+ for (vector<CFileItemPtr>::const_iterator iter = m_vecItems.begin(); iter != m_vecItems.end(); ++iter)
{
- CSingleLock lock(m_lock);
- if (!m_bStartCalled)
+ CFileItemPtr pItem = *iter;
+
+ // Ask the callback if we should abort
+ if ((m_pProgressCallback && m_pProgressCallback->Abort()) || m_bStop)
+ break;
+
+ try
{
- OnLoaderStart();
- m_bStartCalled = true;
+ if (LoadItemCached(pItem.get()) && m_pObserver)
+ m_pObserver->OnItemLoaded(pItem.get());
}
- }
-
- while (!m_bStop)
- {
- CSingleLock lock(m_lock);
- CFileItemPtr pItem;
- vector<CFileItemPtr>::iterator iter = m_vecItems.begin();
- if (iter != m_vecItems.end())
+ catch (...)
{
- pItem = *iter;
- m_vecItems.erase(iter);
+ CLog::Log(LOGERROR, "CBackgroundInfoLoader::LoadItemCached - Unhandled exception for item %s", pItem->GetPath().c_str());
}
+ }
- if (pItem == NULL)
- break;
+ // Stage 2: All "slow" stuff that we need to lookup
+ for (vector<CFileItemPtr>::const_iterator iter = m_vecItems.begin(); iter != m_vecItems.end(); ++iter)
+ {
+ CFileItemPtr pItem = *iter;
// Ask the callback if we should abort
if ((m_pProgressCallback && m_pProgressCallback->Abort()) || m_bStop)
break;
- lock.Leave();
try
{
- if (LoadItem(pItem.get()) && m_pObserver)
+ if (LoadItemLookup(pItem.get()) && m_pObserver)
m_pObserver->OnItemLoaded(pItem.get());
}
catch (...)
{
- CLog::Log(LOGERROR, "%s::LoadItem - Unhandled exception for item %s", __FUNCTION__, pItem->GetPath().c_str());
+ CLog::Log(LOGERROR, "CBackgroundInfoLoader::LoadItemLookup - Unhandled exception for item %s", pItem->GetPath().c_str());
}
}
}
- CSingleLock lock(m_lock);
- if (m_nActiveThreads == 1)
- OnLoaderFinish();
- m_nActiveThreads--;
-
+ OnLoaderFinish();
+ m_bIsLoading = false;
}
catch (...)
{
- m_nActiveThreads--;
+ m_bIsLoading = false;
CLog::Log(LOGERROR, "%s - Unhandled exception", __FUNCTION__);
}
}
m_pVecItems = &items;
m_bStop = false;
- m_bStartCalled = false;
+ m_bIsLoading = true;
- int nThreads = m_nRequestedThreads;
- if (nThreads == -1)
- nThreads = (m_vecItems.size() / (ITEMS_PER_THREAD+1)) + 1;
-
- if (nThreads > g_advancedSettings.m_bgInfoLoaderMaxThreads)
- nThreads = g_advancedSettings.m_bgInfoLoaderMaxThreads;
-
- m_nActiveThreads = nThreads;
- for (int i=0; i < nThreads; i++)
- {
- CThread *pThread = new CThread(this, "BackgroundLoader");
- pThread->Create();
+ m_thread = new CThread(this, "BackgroundLoader");
+ m_thread->Create();
#ifndef TARGET_POSIX
- pThread->SetPriority(THREAD_PRIORITY_BELOW_NORMAL);
+ m_thread->SetPriority(THREAD_PRIORITY_BELOW_NORMAL);
#endif
- m_workers.push_back(pThread);
- }
-
}
void CBackgroundInfoLoader::StopAsync()
{
StopAsync();
- for (int i=0; i<(int)m_workers.size(); i++)
+ if (m_thread)
{
- m_workers[i]->StopThread();
- delete m_workers[i];
+ m_thread->StopThread();
+ delete m_thread;
+ m_thread = NULL;
}
-
- m_workers.clear();
m_vecItems.clear();
m_pVecItems = NULL;
- m_nActiveThreads = 0;
+ m_bIsLoading = false;
}
bool CBackgroundInfoLoader::IsLoading()
{
- return m_nActiveThreads > 0;
+ return m_bIsLoading;
}
void CBackgroundInfoLoader::SetObserver(IBackgroundLoaderObserver* pObserver)