diff --git a/src/lib/nfs/Connection.cxx b/src/lib/nfs/Connection.cxx index 949ba7bf3..3c5ca5d09 100644 --- a/src/lib/nfs/Connection.cxx +++ b/src/lib/nfs/Connection.cxx @@ -91,14 +91,18 @@ NfsConnection::CancellableCallback::Read(nfs_context *ctx, struct nfsfh *fh, } inline void -NfsConnection::CancellableCallback::CancelAndScheduleClose(struct nfsfh *fh) noexcept +NfsConnection::CancellableCallback::CancelAndScheduleClose(struct nfsfh *fh, + DisposablePointer &&_dispose_value) noexcept { assert(connection.GetEventLoop().IsInside()); assert(!open); assert(close_fh == nullptr); + assert(!dispose_value); assert(fh != nullptr); close_fh = fh; + dispose_value = std::move(_dispose_value); + Cancel(); } @@ -371,10 +375,11 @@ NfsConnection::Close(struct nfsfh *fh) noexcept } void -NfsConnection::CancelAndClose(struct nfsfh *fh, NfsCallback &callback) noexcept +NfsConnection::CancelAndClose(struct nfsfh *fh, DisposablePointer dispose_value, + NfsCallback &callback) noexcept { CancellableCallback &cancel = callbacks.Get(callback); - cancel.CancelAndScheduleClose(fh); + cancel.CancelAndScheduleClose(fh, std::move(dispose_value)); } void diff --git a/src/lib/nfs/Connection.hxx b/src/lib/nfs/Connection.hxx index e01b1e206..3c2dbfbb3 100644 --- a/src/lib/nfs/Connection.hxx +++ b/src/lib/nfs/Connection.hxx @@ -7,6 +7,7 @@ #include "event/SocketEvent.hxx" #include "event/CoarseTimerEvent.hxx" #include "event/DeferEvent.hxx" +#include "util/DisposablePointer.hxx" #include "util/IntrusiveList.hxx" #include @@ -41,6 +42,12 @@ class NfsConnection { */ struct nfsfh *close_fh; + /** + * An arbitrary value that will be disposed of after + * cancellation completes. + */ + DisposablePointer dispose_value; + public: explicit CancellableCallback(NfsCallback &_callback, NfsConnection &_connection, @@ -61,7 +68,8 @@ class NfsConnection { * Cancel the operation and schedule a call to * nfs_close_async() with the given file handle. */ - void CancelAndScheduleClose(struct nfsfh *fh) noexcept; + void CancelAndScheduleClose(struct nfsfh *fh, + DisposablePointer &&_dispose_value) noexcept; /** * Called by NfsConnection::DestroyContext() right @@ -226,8 +234,12 @@ public: /** * Like Cancel(), but also close the specified NFS file * handle. + * + * @param dispose_value an arbitrary value that will be + * disposed of after cancellation completes */ - void CancelAndClose(struct nfsfh *fh, NfsCallback &callback) noexcept; + void CancelAndClose(struct nfsfh *fh, DisposablePointer dispose_value, + NfsCallback &callback) noexcept; protected: virtual void OnNfsConnectionError(std::exception_ptr e) noexcept = 0; diff --git a/src/lib/nfs/FileReader.cxx b/src/lib/nfs/FileReader.cxx index 466491630..8e33b1a3d 100644 --- a/src/lib/nfs/FileReader.cxx +++ b/src/lib/nfs/FileReader.cxx @@ -59,7 +59,7 @@ NfsFileReader::CancelOrClose() noexcept else if (state > State::OPEN) /* one async operation in progress: cancel it and defer the nfs_close_async() call */ - connection->CancelAndClose(fh, *this); + connection->CancelAndClose(fh, {}, *this); else if (state > State::MOUNT) /* we don't have a file handle yet - just cancel the async operation */