aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
authorMaximilian Bosch <maximilian@mbosch.me>2021-10-07 23:58:02 +0200
committerMaximilian Bosch <maximilian@mbosch.me>2021-10-07 23:58:02 +0200
commit0872659002d17dc7941b94075b3b9a54169d173f (patch)
tree09d8a124d7553c3af71164472e244e31c23c5ca4 /src/libstore
parent844dd901a7debe8b03ec93a7f717b6c4038dc572 (diff)
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.
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/filetransfer.cc21
1 files changed, 19 insertions, 2 deletions
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<curlFileTransfer> makeCurlFileTransfer()
+{
+ return make_ref<curlFileTransfer>();
+}
+
ref<FileTransfer> getFileTransfer()
{
- static ref<FileTransfer> fileTransfer = makeFileTransfer();
+ static ref<curlFileTransfer> 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<FileTransfer> makeFileTransfer()
{
- return make_ref<curlFileTransfer>();
+ return makeCurlFileTransfer();
}
std::future<FileTransferResult> FileTransfer::enqueueFileTransfer(const FileTransferRequest & request)