diff -r 59984e68247d -r 6abfb1094884 phonebookengines/cntlistmodel/src/cntcache_p.cpp --- a/phonebookengines/cntlistmodel/src/cntcache_p.cpp Thu Sep 09 16:37:32 2010 +0300 +++ b/phonebookengines/cntlistmodel/src/cntcache_p.cpp Tue Sep 21 17:07:25 2010 +0300 @@ -24,6 +24,7 @@ #include #include #include + #include "cntcache.h" #include "cntcache_p.h" #include @@ -37,14 +38,16 @@ // in this way the client can request the job again if wanted static const int CntMaxInfoJobs = 20; static const int CntMaxIconJobs = 20; -// amount of milliseconds to postpone the jobs if the UI is very active -static const int PostponeJobsMilliSeconds = 300; // the event for starting to process all outstanding jobs static const QEvent::Type ProcessJobsEvent = QEvent::User; // the id that states that no icon is currently pending from thumbnail manager static const int NoIconRequest = -1; // the id that states that there is no job with that key static const int NoSuchJob = -1; +// different states of postponement +static const int JobsNotPostponed = 0; +static const int JobsPostponedForDuration = 1; +static const int JobsPostponedUntilResume = 2; const char *CNT_INFO_PROVIDER_EXTENSION_PLUGIN_DIRECTORY = "/resource/qt/plugins/contacts/infoproviders/"; @@ -56,10 +59,10 @@ */ CntCacheThread::CntCacheThread() : mContactManager(new QContactManager()), - mStarted(false), mProcessingJobs(false), - mPostponeJobs(false), - mIconRequestId(NoIconRequest) + mJobsPostponed(JobsNotPostponed), + mIconRequestId(NoIconRequest), + mTimer(new QTimer()) { CNT_ENTRY @@ -69,16 +72,13 @@ // load dynamic provider plugins QDir pluginsDir(CNT_INFO_PROVIDER_EXTENSION_PLUGIN_DIRECTORY); - foreach (QString fileName, pluginsDir.entryList(QDir::Files)) - { + foreach (QString fileName, pluginsDir.entryList(QDir::Files)) { // Create plugin loader QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName)); - if ( pluginLoader.load() ) - { + if (pluginLoader.load()) { CntInfoProviderFactory *factory = qobject_cast(pluginLoader.instance()); - if (factory) - { + if (factory) { CntInfoProvider *provider = factory->infoProvider(); mInfoProviders.insert(provider, provider->supportedFields()); } @@ -94,7 +94,7 @@ this, SLOT(onInfoFieldReady(CntInfoProvider*, int, ContactInfoField, const QString&))); } - + // create & connect the thumbnail manager mThumbnailManager = new ThumbnailManager(this); mThumbnailManager->setMode(ThumbnailManager::Default); @@ -102,6 +102,9 @@ mThumbnailManager->setThumbnailSize(ThumbnailManager::ThumbnailSmall); connect(mThumbnailManager, SIGNAL(thumbnailReady(QPixmap, void *, int, int)), this, SLOT(onIconReady(QPixmap, void *, int, int))); + + mTimer->setSingleShot(true); + connect(mTimer, SIGNAL(timeout()), this, SLOT(resumeJobs())); CNT_EXIT } @@ -116,7 +119,6 @@ delete mContactManager; disconnect(this); - mJobMutex.lock(); mInfoJobs.clear(); mCancelledInfoJobs.clear(); mIconJobs.clear(); @@ -133,23 +135,6 @@ qDeleteAll(mInfoProviders.keys()); mInfoProviders.clear(); - mJobMutex.unlock(); - - exit(); - wait(); - - CNT_EXIT -} - -/*! - Starts the event loop for this thread. - */ -void CntCacheThread::run() -{ - CNT_ENTRY - - exec(); - CNT_EXIT } @@ -166,26 +151,15 @@ if (contactId <= 0) return; - mJobMutex.lock(); - int index = infoJobIndex(contactId); if (index != NoSuchJob) { // if the job already exists, update the priority if (priority < mInfoJobs.at(index).second) { mInfoJobs[index] = QPair(contactId,priority); } - mJobMutex.unlock(); return; } - if (!mStarted) { - // starting the event loop; minimum priority is used as this thread - // should interfere as little as possible with more time-critical tasks, - // like updating the UI during scrolling - start(QThread::IdlePriority); - mStarted = true; - } - if (!mProcessingJobs) { // new job => start processing jobs mProcessingJobs = true; @@ -205,8 +179,6 @@ // cancelled jobs in case it is there mCancelledInfoJobs.removeOne(contactId); - mJobMutex.unlock(); - CNT_EXIT } @@ -223,15 +195,12 @@ if (iconName.isEmpty()) return; - mJobMutex.lock(); - int index = iconJobIndex(iconName); if (index != NoSuchJob) { // if the job already exists, update the priority if (priority < mIconJobs.at(index).second) { mIconJobs[index] = QPair(iconName,priority); } - mJobMutex.unlock(); return; } @@ -254,20 +223,45 @@ // cancelled jobs in case it is there mCancelledIconJobs.removeOne(iconName); - mJobMutex.unlock(); + CNT_EXIT +} + +/*! + Postpones outstanding jobs until milliseconds ms has passed or resumeJobs() is called. + This should be called if the client wants to reserve more CPU time for some urgent tasks. + + \param milliseconds The duration of the delay; 0, which is the default, means to delay + until resumeJobs() is called + */ +void CntCacheThread::postponeJobs(int milliseconds) +{ + CNT_ENTRY_ARGS("ms =" << milliseconds << " type =" << mJobsPostponed) + + Q_ASSERT(milliseconds >= 0); + + if (milliseconds == 0) { + mTimer->stop(); + mJobsPostponed = JobsPostponedUntilResume; + } else if (mJobsPostponed != JobsPostponedUntilResume) { + mTimer->stop(); + mJobsPostponed = JobsPostponedForDuration; + mTimer->start(milliseconds); + } CNT_EXIT } /*! - Postpones outstanding jobs for a few tenths of a second. This should be called if - the client wants to reserve more CPU time for some urgent task. + Postpones outstanding jobs until resumeJobs() is called. This must always be called after + postponeJobs. */ -void CntCacheThread::postponeJobs() +void CntCacheThread::resumeJobs() { CNT_ENTRY - mPostponeJobs = true; + mTimer->stop(); + mJobsPostponed = JobsNotPostponed; + HbApplication::instance()->postEvent(this, new QEvent(ProcessJobsEvent)); CNT_EXIT } @@ -283,7 +277,7 @@ return true; } - return QThread::event(event); + return QObject::event(event); } /*! @@ -296,48 +290,34 @@ { CNT_ENTRY + bool hasDoneJobs = false; + forever { - mJobMutex.lock(); int infoJobs = mInfoJobs.count(); int iconJobs = mIconJobs.count(); int totalJobs = infoJobs + iconJobs + mCancelledInfoJobs.count() + mCancelledIconJobs.count(); - - if (totalJobs == 0 || totalJobs == iconJobs && mIconRequestId != NoIconRequest || mPostponeJobs) { - if (mPostponeJobs) { - // client has requested a pause in activies (e.g. due to high UI activity) - mPostponeJobs = false; - if (totalJobs > 0) { - QTimer::singleShot(PostponeJobsMilliSeconds, this, SLOT(processJobs())); - } - else { - mProcessingJobs = false; - } - } - else { + + if (totalJobs == 0 || totalJobs == iconJobs && mIconRequestId != NoIconRequest || mJobsPostponed != JobsNotPostponed) { + if (mJobsPostponed == JobsNotPostponed || totalJobs == 0) { mProcessingJobs = false; } - - mJobMutex.unlock(); - - if (totalJobs == 0) { + + if (totalJobs == 0 && hasDoneJobs) { emit allJobsDone(); } - + break; } - - bool doInfoJob = infoJobs > 0; // && (iconJobs == 0 || mIconRequestId != NoIconRequest || qrand() % (infoJobs + iconJobs) < infoJobs); - if (doInfoJob) { + if (infoJobs > 0) { // get next job int contactId = takeNextInfoJob(); - mJobMutex.unlock(); - + // fetch qcontact QContactFetchHint restrictions; restrictions.setOptimizationHints(QContactFetchHint::NoRelationships); QContact contact = mContactManager->contact(contactId, restrictions); - + // request contact info from providers QMapIterator i(mInfoProviders); while (i.hasNext()) { @@ -352,21 +332,20 @@ QString iconName = takeNextIconJob(); mIconRequestId = mThumbnailManager->getThumbnail(iconName, NULL, 0); mIconRequestName = iconName; - mJobMutex.unlock(); } else { if (mCancelledInfoJobs.count() > 0) { int contactId = mCancelledInfoJobs.takeLast(); - mJobMutex.unlock(); emit infoCancelled(contactId); } else if (mCancelledIconJobs.count() > 0) { QString iconName = mCancelledIconJobs.takeFirst(); - mJobMutex.unlock(); emit iconCancelled(iconName); } } - + + hasDoneJobs = true; + // allow signals to be passed from providers and from the client HbApplication::processEvents(); } @@ -408,7 +387,6 @@ Q_UNUSED(id); Q_UNUSED(data); - mJobMutex.lock(); Q_ASSERT(id == mIconRequestId && !mIconRequestName.isEmpty()); if (!mProcessingJobs) { // job loop quit while waiting for this icon, so restart it @@ -416,7 +394,6 @@ HbApplication::instance()->postEvent(this, new QEvent(ProcessJobsEvent)); } mIconRequestId = NoIconRequest; - mJobMutex.unlock(); if (error == 0) { emit iconUpdated(mIconRequestName, HbIcon(pixmap)); @@ -426,7 +403,7 @@ } /*! - Finds out the index of an info job in the job list. Job mutex must be held when calling this function. + Finds out the index of an info job in the job list. \return index of the contact in the job list, or NoSuchJob if no job is scheduled for the contact */ @@ -495,7 +472,7 @@ } /*! - Finds out the index of an icon job in the job list. Job mutex must be held when calling this function. + Finds out the index of an icon job in the job list. \return index of the icon in the job list, or NoSuchJob if a job for the icon is not scheduled. */ @@ -510,3 +487,5 @@ return NoSuchJob; } + +