mirror of
https://github.com/NixOS/nix.git
synced 2025-11-09 03:56:01 +01:00
fix(libstore/filetransfer): prevent double callback invocation on interrupt during retry
Fix a race condition where interrupting a download (via Ctrl-C) during a retry attempt could cause a crash. When `enqueueItem()` throws because the download thread is shutting down, the exception would propagate without setting `done=true`, causing the `TransferItem` destructor to invoke the callback a second time. This triggered an assertion failure in `Callback::rethrow()` with: `Assertion '!prev' failed` and the error message `cannot enqueue download request because the download thread is shutting down`. The fix catches the exception from `enqueueItem()` and calls `fail()` to properly complete the transfer, ensuring the callback is invoked exactly once.
This commit is contained in:
parent
da637a05da
commit
560a596de7
1 changed files with 8 additions and 1 deletions
|
|
@ -598,7 +598,14 @@ struct curlFileTransfer : public FileTransfer
|
||||||
decompressionSink.reset();
|
decompressionSink.reset();
|
||||||
errorSink.reset();
|
errorSink.reset();
|
||||||
embargo = std::chrono::steady_clock::now() + std::chrono::milliseconds(ms);
|
embargo = std::chrono::steady_clock::now() + std::chrono::milliseconds(ms);
|
||||||
|
try {
|
||||||
fileTransfer.enqueueItem(shared_from_this());
|
fileTransfer.enqueueItem(shared_from_this());
|
||||||
|
} catch (const nix::Error & e) {
|
||||||
|
// If enqueue fails (e.g., during shutdown), fail the transfer properly
|
||||||
|
// instead of letting the exception propagate, which would leave done=false
|
||||||
|
// and cause the destructor to attempt a second callback invocation
|
||||||
|
fail(std::move(exc));
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
fail(std::move(exc));
|
fail(std::move(exc));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue