From: <ag...@us...> - 2011-12-14 20:45:28
|
Revision: 2640 http://zoolib.svn.sourceforge.net/zoolib/?rev=2640&view=rev Author: agreen Date: 2011-12-14 20:45:21 +0000 (Wed, 14 Dec 2011) Log Message: ----------- Use the worker's Detach callable to manage notification of completion. If fCallable_Connection propagated and exception then the prior mechanism would break. Modified Paths: -------------- trunk/zoolib/source/cxx/zoolib/ZServer.cpp trunk/zoolib/source/cxx/zoolib/ZServer.h Modified: trunk/zoolib/source/cxx/zoolib/ZServer.cpp =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZServer.cpp 2011-12-14 20:42:34 UTC (rev 2639) +++ trunk/zoolib/source/cxx/zoolib/ZServer.cpp 2011-12-14 20:45:21 UTC (rev 2640) @@ -38,8 +38,8 @@ void ZServer::Finalize() { ZGuardRMtx guard(fMtx); - ZAssert(!fWorker); - ZAssert(!fFactory); + ZAssert(not fWorker); + ZAssert(not fFactory); fRoster.Clear(); fCallable_Connection.Clear(); guard.Release(); @@ -70,7 +70,9 @@ fFactory = iFactory; fCallable_Connection = iCallable_Connection; - fWorker = new ZWorker(sCallable(sWeakRef(this), &ZServer::pWork)); + fWorker = new ZWorker + (sCallable(sWeakRef(this), &ZServer::pWork), + sCallable(sWeakRef(this), &ZServer::pWorkDetached)); fWorker->Attach(iCaller); @@ -92,14 +94,19 @@ void ZServer::StopWait() { ZAcqMtx acq(fMtx); + if (ZRef<ZStreamerRWFactory> theFactory = fFactory) { fFactory.Clear(); theFactory->Cancel(); } - fCnd.Broadcast(); - while (fWorker) - fCnd.Wait(fMtx); + + if (fWorker) + { + fWorker->Wake(); + while (fWorker) + fCnd.Wait(fMtx); + } } void ZServer::KillConnections() @@ -139,30 +146,36 @@ { ZGuardRMtx guard(fMtx); - if (ZRef<ZStreamerRWFactory,false> theFactory = fFactory) + if (ZRef<ZStreamerRWFactory> theFactory = fFactory) { - fWorker.Clear(); - fCnd.Broadcast(); - return false; - } - else - { guard.Release(); if (ZRef<ZStreamerRW> theSRW = theFactory->MakeStreamerRW()) { guard.Acquire(); if (ZRef<Callable_Connection> theCallable = fCallable_Connection) { - ZRef<ZStreamerRWCon> theSRWCon = theSRW.DynamicCast<ZStreamerRWCon>(); - ZRef<ZRoster::Entry> theEntry = - fRoster->MakeEntry(sBindR(sCallable(spKill), theSRWCon), null); guard.Release(); - theCallable->Call(theEntry, theSRW); + try + { + ZRef<ZCallable_Void> theCallable_Kill = + sBindR(sCallable(spKill), theSRW.DynamicCast<ZStreamerRWCon>()); + theCallable->Call(fRoster->MakeEntry(theCallable_Kill, null), theSRW); + } + catch (...) + {} } } + iWorker->Wake(); + return true; } - iWorker->Wake(); - return true; + return false; } +void ZServer::pWorkDetached(ZRef<ZWorker> iWorker) + { + ZAcqMtx acq(fMtx); + fWorker.Clear(); + fCnd.Broadcast(); + } + } // namespace ZooLib Modified: trunk/zoolib/source/cxx/zoolib/ZServer.h =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZServer.h 2011-12-14 20:42:34 UTC (rev 2639) +++ trunk/zoolib/source/cxx/zoolib/ZServer.h 2011-12-14 20:45:21 UTC (rev 2640) @@ -62,6 +62,7 @@ private: bool pWork(ZRef<ZWorker> iWorker); + void pWorkDetached(ZRef<ZWorker> iWorker); ZMtx fMtx; ZCnd fCnd; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |