From: <ag...@us...> - 2011-12-14 20:42:40
|
Revision: 2639 http://zoolib.svn.sourceforge.net/zoolib/?rev=2639&view=rev Author: agreen Date: 2011-12-14 20:42:34 +0000 (Wed, 14 Dec 2011) Log Message: ----------- Let the waiter thread exit when there's no pending jobs, so ZThread::sWaitTillAllThreadsExit doesn't block. Modified Paths: -------------- trunk/zoolib/source/cxx/zoolib/ZCallScheduler.cpp trunk/zoolib/source/cxx/zoolib/ZCallScheduler.h Modified: trunk/zoolib/source/cxx/zoolib/ZCallScheduler.cpp =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZCallScheduler.cpp 2011-12-14 20:41:10 UTC (rev 2638) +++ trunk/zoolib/source/cxx/zoolib/ZCallScheduler.cpp 2011-12-14 20:42:34 UTC (rev 2639) @@ -27,18 +27,26 @@ // ================================================================================================= #pragma mark - -#pragma mark * ZCallScheduler +#pragma mark * Helpers static ZCallScheduler* spScheduler; +namespace { // anonymous + +struct Deleter { ~Deleter() { delete spScheduler; } } spDeleter; + +} // anonymous namespace + +// ================================================================================================= +#pragma mark - +#pragma mark * ZCallScheduler + ZCallScheduler* ZCallScheduler::sGet() { - if (!spScheduler) + if (not spScheduler) { ZCallScheduler* theScheduler = new ZCallScheduler; - if (ZAtomic_CompareAndSwapPtr(&spScheduler, nullptr, theScheduler)) - ZThread::sCreate_T<ZCallScheduler*>(spRun, theScheduler); - else + if (not ZAtomic_CompareAndSwapPtr(&spScheduler, nullptr, theScheduler)) delete theScheduler; } return spScheduler; @@ -48,7 +56,7 @@ { using namespace ZUtil_STL; - ZAcqMtxR acq(fMtxR); + ZAcqMtx acq(fMtx); const Job theJob(iCaller, iCallable); @@ -70,7 +78,7 @@ bool ZCallScheduler::IsAwake(const ZRef<ZCaller>& iCaller, const ZRef<ZCallable_Void>& iCallable) { - ZAcqMtxR acq(fMtxR); + ZAcqMtx acq(fMtx); const Job theJob(iCaller, iCallable); @@ -81,11 +89,15 @@ return false; } +ZCallScheduler::ZCallScheduler() +: fThreadRunning(false) + {} + void ZCallScheduler::pNextCallAt(ZTime iSystemTime, const Job& iJob) { using namespace ZUtil_STL; - ZAcqMtxR acq(fMtxR); + ZAcqMtx acq(fMtx); set<JobTime>::iterator iterJT = fJobTimes.lower_bound(make_pair(iJob, 0.0)); if (iterJT != fJobTimes.end() && iterJT->first == iJob) @@ -104,6 +116,11 @@ { sInsertMustNotContain(fJobTimes, make_pair(iJob, iSystemTime)); sInsertMustNotContain(fTimeJobs, make_pair(iSystemTime, iJob)); + if (not fThreadRunning) + { + fThreadRunning = true; + ZThread::sCreate_T<ZCallScheduler*>(spRun, this); + } fCnd.Broadcast(); } } @@ -112,12 +129,19 @@ { using namespace ZUtil_STL; - ZGuardRMtxR guard(fMtxR); + ZGuardRMtx guard(fMtx); for (;;) { if (fTimeJobs.empty()) { - fCnd.Wait(fMtxR); + // Nothing pending, wait 100ms in case something else comes along. + fCnd.WaitFor(fMtx, 0.1); + if (fTimeJobs.empty()) + { + // Still nothing pending, exit thread. + fThreadRunning = false; + break; + } } else { @@ -125,7 +149,7 @@ const double delta = begin->first - ZTime::sSystem(); if (delta > 0) { - fCnd.WaitFor(fMtxR, delta); + fCnd.WaitFor(fMtx, delta); } else { Modified: trunk/zoolib/source/cxx/zoolib/ZCallScheduler.h =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZCallScheduler.h 2011-12-14 20:41:10 UTC (rev 2638) +++ trunk/zoolib/source/cxx/zoolib/ZCallScheduler.h 2011-12-14 20:42:34 UTC (rev 2639) @@ -51,6 +51,8 @@ bool IsAwake(const ZRef<ZCaller>& iCaller, const ZRef<ZCallable_Void>& iCallable); private: + ZCallScheduler(); + typedef std::pair<ZRef<ZCaller>,ZRef<ZCallable_Void> > Job; void pNextCallAt(ZTime iSystemTime, const Job& iJob); @@ -58,9 +60,11 @@ void pRun(); static void spRun(ZCallScheduler*); - ZMtxR fMtxR; + ZMtx fMtx; ZCnd fCnd; + bool fThreadRunning; + typedef std::pair<ZTime,Job> TimeJob; typedef std::pair<Job,ZTime> JobTime; std::set<TimeJob> fTimeJobs; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |