about summary refs log tree commit diff
path: root/src/libstore/download.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-01-17T17·21+0100
committerEelco Dolstra <edolstra@gmail.com>2017-01-17T17·21+0100
commitcc3b93c991e04aff49a44dbced53f070a06f426e (patch)
treebc88ad9093faabd477ce935aedb5bd6a09459107 /src/libstore/download.cc
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/download.cc')
-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 954044c234..42873d9e8a 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;