aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-01-17 18:21:02 +0100
committerEelco Dolstra <edolstra@gmail.com>2017-01-17 18:21:02 +0100
commitcc3b93c991e04aff49a44dbced53f070a06f426e (patch)
treebc88ad9093faabd477ce935aedb5bd6a09459107 /src/libstore
parentc0d55f918379f46b87e43457745895439a85555c (diff)
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.
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/download.cc20
1 files changed, 15 insertions, 5 deletions
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
@@ -324,20 +324,30 @@ 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<CURL *, std::shared_ptr<DownloadItem>> items;
bool quit = false;