From 0872659002d17dc7941b94075b3b9a54169d173f Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Thu, 7 Oct 2021 23:58:02 +0200 Subject: nix repl: properly deal with interruptions When I stop a download with Ctrl-C in a `nix repl` of a flake, the REPL refuses to do any other downloads: nix-repl> builtins.getFlake "nix-serve" [0.0 MiB DL] downloading 'https://api.github.com/repos/edolstra/nix-serve/tarball/e9828a9e01a14297d15ca41 error: download of 'https://api.github.com/repos/edolstra/nix-serve/tarball/e9828a9e01a14297d15ca416e5a9415d4972b0f0' was interrupted [0.0 MiB DL] nix-repl> builtins.getFlake "nix-serve" error: interrupted by the user [0.0 MiB DL] To fix this issue, two changes were necessary: * Reset the global `_isInterrupted` variable: only because a single operation was aborted, it should still be possible to continue the session. * Recreate a `fileTransfer`-instance if the current one was shut down by an abort. --- src/libstore/filetransfer.cc | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src/libstore') diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index 2cf35ec83..758862e60 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -716,15 +716,32 @@ struct curlFileTransfer : public FileTransfer } }; +ref makeCurlFileTransfer() +{ + return make_ref(); +} + ref getFileTransfer() { - static ref fileTransfer = makeFileTransfer(); + static ref fileTransfer = makeCurlFileTransfer(); + + // this has to be done in its own scope to make sure that the lock is released + // before creating a new fileTransfer instance. + auto needsRecreation = [&]() -> bool { + auto state = fileTransfer->state_.lock(); + return state->quit; + }; + + if (needsRecreation()) { + fileTransfer = makeCurlFileTransfer(); + } + return fileTransfer; } ref makeFileTransfer() { - return make_ref(); + return makeCurlFileTransfer(); } std::future FileTransfer::enqueueFileTransfer(const FileTransferRequest & request) -- cgit v1.2.3