diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index 76d134093..73fe1bdd9 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -48,7 +48,7 @@ struct curlFileTransfer : public FileTransfer std::random_device rd; std::mt19937 mt19937; - struct TransferItem : public std::enable_shared_from_this + struct TransferItem : public std::enable_shared_from_this, public FileTransfer::Item { curlFileTransfer & fileTransfer; FileTransferRequest request; @@ -849,7 +849,7 @@ struct curlFileTransfer : public FileTransfer } } - void enqueueItem(ref item) + ItemHandle enqueueItem(ref item) { if (item->request.data && item->request.uri.scheme() != "http" && item->request.uri.scheme() != "https" && item->request.uri.scheme() != "s3") @@ -864,19 +864,20 @@ struct curlFileTransfer : public FileTransfer #ifndef _WIN32 // TODO need graceful async exit support on Windows? writeFull(wakeupPipe.writeSide.get(), " "); #endif + + return ItemHandle(static_cast(*item)); } - void enqueueFileTransfer(const FileTransferRequest & request, Callback callback) override + ItemHandle enqueueFileTransfer(const FileTransferRequest & request, Callback callback) override { /* Handle s3:// URIs by converting to HTTPS and optionally adding auth */ if (request.uri.scheme() == "s3") { auto modifiedRequest = request; modifiedRequest.setupForS3(); - enqueueItem(make_ref(*this, std::move(modifiedRequest), std::move(callback))); - return; + return enqueueItem(make_ref(*this, std::move(modifiedRequest), std::move(callback))); } - enqueueItem(make_ref(*this, request, std::move(callback))); + return enqueueItem(make_ref(*this, request, std::move(callback))); } }; diff --git a/src/libstore/include/nix/store/filetransfer.hh b/src/libstore/include/nix/store/filetransfer.hh index 0523f79c7..257c90509 100644 --- a/src/libstore/include/nix/store/filetransfer.hh +++ b/src/libstore/include/nix/store/filetransfer.hh @@ -226,6 +226,26 @@ class Store; struct FileTransfer { +protected: + class Item + {}; + +public: + /** + * An opaque handle to the file transfer. Can be used to reference an in-flight transfer operations. + */ + class ItemHandle + { + std::reference_wrapper item; + friend struct FileTransfer; + + public: + ItemHandle(Item & item) + : item(item) + { + } + }; + virtual ~FileTransfer() {} /** @@ -233,7 +253,8 @@ struct FileTransfer * the download. The future may throw a FileTransferError * exception. */ - virtual void enqueueFileTransfer(const FileTransferRequest & request, Callback callback) = 0; + virtual ItemHandle + enqueueFileTransfer(const FileTransferRequest & request, Callback callback) = 0; std::future enqueueFileTransfer(const FileTransferRequest & request);