From d5cf115a3c8d9e1168da8216725ec2189f63210d Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Tue, 26 May 2026 20:25:05 +0200 Subject: [PATCH] libstore: fix file transfer cancellation deadlock file transfer cancellation should not get lost, or bad things happen. fixes #1218, probably Change-Id: I1be9d523236655f1248883d59b2b7ef5db7873a2 --- lix/libstore/filetransfer.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lix/libstore/filetransfer.cc b/lix/libstore/filetransfer.cc index 24c26d37f..06522e0c8 100644 --- a/lix/libstore/filetransfer.cc +++ b/lix/libstore/filetransfer.cc @@ -664,6 +664,22 @@ struct CurlMulti for (auto & [_, item] : items) { item->finish(CURLE_ABORTED_BY_CALLBACK); } + + // make a note that we're dying and acknowledge all pending cancel + // requests by individual transfers. not doing this can cause bugs + // like #1218 in which the process deadlocks waiting for transfers + // to cancel with no download thread to make this happen; this was + // likely caused by a transfer requesting a cancellation *exactly* + // before a signal was received, causing the curl thread to die in + // a hurry without processing cancellations. the transfer is stuck + // from that point on, and since this happened in a destructor the + // entire process locked up solid. curl exceptions could have also + // caused this; we set the `quit` flag just in case to avoid this. + auto lock = state_.lock(); + lock->quit = true; + for (auto & [item, promise] : lock->cancel) { + promise.set_value(); + } }); bool quit = false;