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.
This commit is contained in:
Eelco Dolstra 2017-01-17 18:21:02 +01:00
parent c0d55f9183
commit cc3b93c991
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
4 changed files with 101 additions and 28 deletions

View file

@ -324,20 +324,30 @@ struct CurlDownloader : public Downloader
~CurlDownloader()
{
/* Signal the worker thread to exit. */
{
auto state(state_.lock());
state->quit = true;
}
writeFull(wakeupPipe.writeSide.get(), " ");
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(), " ", 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;