summaryrefslogtreecommitdiffstats
path: root/filedistribution
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2016-09-22 10:31:22 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2016-09-22 10:31:22 +0000
commit7377825a7eb1d04f8cc8d86b321efe16edf73b77 (patch)
tree546ec352f6406c3b8e26d54c232b9181145ab008 /filedistribution
parent409a42037516304250d1d5272978e33d5fd2af71 (diff)
ensure that threads are joined on exceptions.
Diffstat (limited to 'filedistribution')
-rw-r--r--filedistribution/src/apps/filedistributor/filedistributor.cpp42
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();
}
};