diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2016-09-22 10:31:22 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2016-09-22 10:31:22 +0000 |
commit | 7377825a7eb1d04f8cc8d86b321efe16edf73b77 (patch) | |
tree | 546ec352f6406c3b8e26d54c232b9181145ab008 /filedistribution | |
parent | 409a42037516304250d1d5272978e33d5fd2af71 (diff) |
ensure that threads are joined on exceptions.
Diffstat (limited to 'filedistribution')
-rw-r--r-- | filedistribution/src/apps/filedistributor/filedistributor.cpp | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/filedistribution/src/apps/filedistributor/filedistributor.cpp b/filedistribution/src/apps/filedistributor/filedistributor.cpp index daef2099823..7afd21e7e44 100644 --- a/filedistribution/src/apps/filedistributor/filedistributor.cpp +++ b/filedistribution/src/apps/filedistributor/filedistributor.cpp @@ -56,7 +56,29 @@ class FileDistributor : public config::IFetcherCallback<ZookeepersConfig>, const std::shared_ptr<StateServerImpl> _stateServer; private: - std::unique_ptr<std::thread> _downloaderEventLoopThread; + class GuardedThread { + public: + GuardedThread(const GuardedThread &) = delete; + GuardedThread & operator = (const GuardedThread &) = delete; + GuardedThread(const std::shared_ptr<FileDownloader> & downloader) : + _downloader(downloader), + _thread([downloader=_downloader] () { downloader->runEventLoop(); }) + { } + ~GuardedThread() { + _downloader->close(); + if (_thread.joinable()) { + _thread.join(); + } + if ( !_downloader->drained() ) { + LOG(error, "The filedownloader did not drain fully. We will just exit quickly and let a restart repair it for us."); + std::quick_exit(67); + } + } + private: + std::shared_ptr<FileDownloader> _downloader; + std::thread _thread; + }; + std::unique_ptr<GuardedThread> _downloaderEventLoopThread; config::ConfigFetcher _configFetcher; template <class T> @@ -73,14 +95,9 @@ class FileDistributor : public config::IFetcherCallback<ZookeepersConfig>, const FiledistributorConfig& fileDistributorConfig, const FiledistributorrpcConfig& rpcConfig) :_zk(track(new ZKFacade(zooKeepersConfig.zookeeperserverlist))), - _model(track(new FileDistributionModelImpl( - fileDistributorConfig.hostname, - fileDistributorConfig.torrentport, - _zk))), + _model(track(new FileDistributionModelImpl(fileDistributorConfig.hostname, fileDistributorConfig.torrentport, _zk))), _tracker(track(new FileDistributorTrackerImpl(_model))), - _downloader(track(new FileDownloader(_tracker, - fileDistributorConfig.hostname, - fileDistributorConfig.torrentport, + _downloader(track(new FileDownloader(_tracker, fileDistributorConfig.hostname, fileDistributorConfig.torrentport, boost::filesystem::path(fileDistributorConfig.filedbpath)))), _manager(track(new FileDownloaderManager(_downloader, _model))), _rpcHandler(track(new FileDistributorRPC(rpcConfig.connectionspec, _manager))), @@ -88,7 +105,7 @@ class FileDistributor : public config::IFetcherCallback<ZookeepersConfig>, _downloaderEventLoopThread(), _configFetcher(configUri.getContext()) { - _downloaderEventLoopThread = std::make_unique<std::thread>([downloader=_downloader] () { downloader->runEventLoop(); }); + _downloaderEventLoopThread = std::make_unique<GuardedThread>(_downloader); _manager->start(); _rpcHandler->start(); @@ -108,12 +125,7 @@ class FileDistributor : public config::IFetcherCallback<ZookeepersConfig>, //Do not waste time retrying zookeeper operations when going down. _zk->disableRetries(); - _downloader->close(); - _downloaderEventLoopThread->join(); - if ( !_downloader->drained() ) { - LOG(error, "The filedownloader did not drain fully. We will just exit quickly and let a restart repair it for us."); - std::quick_exit(67); - } + _downloaderEventLoopThread.reset(); } }; |