From cc3b93c991e04aff49a44dbced53f070a06f426e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 17 Jan 2017 18:21:02 +0100 Subject: Handle SIGINT etc. via a sigwait() signal handler thread This allows other threads to install callbacks that run in a regular, non-signal context. In particular, we can use this to signal the downloader thread to quit. Closes #1183. --- src/libstore/download.cc | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src/libstore') diff --git a/src/libstore/download.cc b/src/libstore/download.cc index 954044c23..42873d9e8 100644 --- a/src/libstore/download.cc +++ b/src/libstore/download.cc @@ -323,21 +323,31 @@ struct CurlDownloader : public Downloader } ~CurlDownloader() + { + stopWorkerThread(); + + workerThread.join(); + + if (curlm) curl_multi_cleanup(curlm); + } + + void stopWorkerThread() { /* Signal the worker thread to exit. */ { auto state(state_.lock()); state->quit = true; } - writeFull(wakeupPipe.writeSide.get(), " "); - - workerThread.join(); - - if (curlm) curl_multi_cleanup(curlm); + writeFull(wakeupPipe.writeSide.get(), " ", false); } void workerThreadMain() { + /* Cause this thread to be notified on SIGINT. */ + auto callback = createInterruptCallback([&]() { + stopWorkerThread(); + }); + std::map> items; bool quit = false; -- cgit v1.2.3