From f96ae0b367825c0e4433a57a086e03f75b1eab2e Mon Sep 17 00:00:00 2001 From: Yingxin Cheng Date: Mon, 3 Apr 2023 09:48:38 +0800 Subject: [PATCH] crimson/common: improve local_shared_foreign_ptr Make ptr nullable and add necessary operators. Signed-off-by: Yingxin Cheng --- src/crimson/common/local_shared_foreign_ptr.h | 136 +++++++++++++++++- 1 file changed, 130 insertions(+), 6 deletions(-) diff --git a/src/crimson/common/local_shared_foreign_ptr.h b/src/crimson/common/local_shared_foreign_ptr.h index ca4edd4d37a..c4bd1099a02 100644 --- a/src/crimson/common/local_shared_foreign_ptr.h +++ b/src/crimson/common/local_shared_foreign_ptr.h @@ -34,7 +34,9 @@ class local_shared_foreign_ptr { /// Wraps a pointer object and remembers the current core. local_shared_foreign_ptr(seastar::foreign_ptr &&fptr) - : ptr(seastar::make_lw_shared(std::move(fptr))) {} + : ptr(fptr ? seastar::make_lw_shared(std::move(fptr)) : nullptr) { + assert(!ptr || (ptr && *ptr)); + } template friend local_shared_foreign_ptr make_local_shared_foreign( @@ -57,8 +59,10 @@ public: ~local_shared_foreign_ptr() = default; /// Creates a copy of this foreign ptr. Only works if the stored ptr is copyable. - seastar::future> get_foreign() { - return ptr->copy(); + seastar::future> get_foreign() const noexcept { + assert(!ptr || (ptr && *ptr)); + return ptr ? ptr->copy() : + seastar::make_ready_future>(nullptr); } /// Accesses the wrapped object. @@ -80,8 +84,8 @@ public: /// Return the owner-shard of the contained foreign_ptr. unsigned get_owner_shard() const noexcept { - assert(ptr && *ptr); - return ptr->get_owner_shard(); + assert(!ptr || (ptr && *ptr)); + return ptr ? ptr->get_owner_shard() : seastar::this_shard_id(); } /// Checks whether the wrapped pointer is non-null. @@ -95,6 +99,18 @@ public: ptr = std::move(other.ptr); return *this; } + + /// Copy-assigns a \c local_shared_foreign_ptr<>. + local_shared_foreign_ptr& operator=(const local_shared_foreign_ptr& other) noexcept { + ptr = other.ptr; + return *this; + } + + /// Reset the containing ptr + void reset() noexcept { + assert(!ptr || (ptr && *ptr)); + ptr = nullptr; + } }; /// Wraps a smart_ptr T in a local_shared_foreign_ptr<>. @@ -108,9 +124,117 @@ local_shared_foreign_ptr make_local_shared_foreign( template local_shared_foreign_ptr make_local_shared_foreign(T &&ptr) { return make_local_shared_foreign( - seastar::make_foreign(std::forward(ptr))); + ptr ? seastar::make_foreign(std::forward(ptr)) : nullptr); +} + +template +inline bool operator==(const local_shared_foreign_ptr &x, + const local_shared_foreign_ptr &y) { + return x.get() == y.get(); +} + +template +inline bool operator==(const local_shared_foreign_ptr &x, std::nullptr_t) { + return x.get() == nullptr; +} + +template +inline bool operator==(std::nullptr_t, const local_shared_foreign_ptr& y) { + return nullptr == y.get(); +} + +template +inline bool operator!=(const local_shared_foreign_ptr &x, + const local_shared_foreign_ptr &y) { + return x.get() != y.get(); +} + +template +inline bool operator!=(const local_shared_foreign_ptr &x, std::nullptr_t) { + return x.get() != nullptr; +} + +template +inline bool operator!=(std::nullptr_t, const local_shared_foreign_ptr& y) { + return nullptr != y.get(); +} + +template +inline bool operator<(const local_shared_foreign_ptr &x, + const local_shared_foreign_ptr &y) { + return x.get() < y.get(); +} + +template +inline bool operator<(const local_shared_foreign_ptr &x, std::nullptr_t) { + return x.get() < nullptr; +} + +template +inline bool operator<(std::nullptr_t, const local_shared_foreign_ptr& y) { + return nullptr < y.get(); } +template +inline bool operator<=(const local_shared_foreign_ptr &x, + const local_shared_foreign_ptr &y) { + return x.get() <= y.get(); +} + +template +inline bool operator<=(const local_shared_foreign_ptr &x, std::nullptr_t) { + return x.get() <= nullptr; +} + +template +inline bool operator<=(std::nullptr_t, const local_shared_foreign_ptr& y) { + return nullptr <= y.get(); +} + +template +inline bool operator>(const local_shared_foreign_ptr &x, + const local_shared_foreign_ptr &y) { + return x.get() > y.get(); +} + +template +inline bool operator>(const local_shared_foreign_ptr &x, std::nullptr_t) { + return x.get() > nullptr; +} + +template +inline bool operator>(std::nullptr_t, const local_shared_foreign_ptr& y) { + return nullptr > y.get(); +} + +template +inline bool operator>=(const local_shared_foreign_ptr &x, + const local_shared_foreign_ptr &y) { + return x.get() >= y.get(); +} + +template +inline bool operator>=(const local_shared_foreign_ptr &x, std::nullptr_t) { + return x.get() >= nullptr; +} + +template +inline bool operator>=(std::nullptr_t, const local_shared_foreign_ptr& y) { + return nullptr >= y.get(); +} + +} + +namespace std { + +template +struct hash> + : private hash::element_type *> { + size_t operator()(const crimson::local_shared_foreign_ptr& p) const { + return hash::element_type *>::operator()(p.get()); + } +}; + } namespace seastar { -- 2.39.5