From fa0ea1368d25acd8bdeb0b5e65026da10b730ecb Mon Sep 17 00:00:00 2001 From: Steve Atherton Date: Sat, 22 Oct 2022 17:55:02 -0700 Subject: [PATCH] Now that IO operation cancellation is safe, explictly cancel all pending operations during shutdown in the operations vector or in the caches. --- fdbserver/VersionedBTree.actor.cpp | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/fdbserver/VersionedBTree.actor.cpp b/fdbserver/VersionedBTree.actor.cpp index 69a4ef6376..d1d9c74415 100644 --- a/fdbserver/VersionedBTree.actor.cpp +++ b/fdbserver/VersionedBTree.actor.cpp @@ -1815,9 +1815,17 @@ ACTOR Future redwoodMetricsLogger() { } // Holds an index of recently used objects. -// ObjectType must have the methods -// bool evictable() const; // return true if the entry can be evicted -// Future onEvictable() const; // ready when entry can be evicted +// ObjectType must have these methods +// +// // Returns true iff the entry can be evicted +// bool evictable() const; +// +// // Ready when object is safe to evict from cache +// Future onEvictable() const; +// +// // Ready when object destruction is safe +// // Should cancel pending async operations that are safe to cancel when cache is being destroyed +// Future cancel() const; template class ObjectCache : NonCopyable { struct Entry; @@ -2052,11 +2060,10 @@ public: state typename CacheT::iterator i = self->cache.begin(); while (i != self->cache.end()) { - if (!i->second.item.evictable()) { - wait(i->second.item.onEvictable()); - } + wait(i->second.item.cancel()); ++i; } + self->cache.clear(); return Void(); } @@ -2122,6 +2129,13 @@ public: // Entry is evictable when its write and read futures are ready, even if they are // errors, so any buffers they hold are no longer needed by the underlying file actors Future onEvictable() const { return ready(readFuture) && ready(writeFuture); } + + // Read and write futures are safe to cancel so just cancel them and return + Future cancel() { + writeFuture.cancel(); + readFuture.cancel(); + return Void(); + } }; typedef ObjectCache PageCacheT; @@ -3782,6 +3796,9 @@ public: self->ioLock.kill(); debug_printf("DWALPager(%s) shutdown cancel operations\n", self->filename.c_str()); + for (auto& f : self->operations) { + f.cancel(); + } self->operations.clear(); debug_printf("DWALPager(%s) shutdown destroy page cache\n", self->filename.c_str());