]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/common: improve local_shared_foreign_ptr
authorYingxin Cheng <yingxin.cheng@intel.com>
Mon, 3 Apr 2023 01:48:38 +0000 (09:48 +0800)
committerMatan Breizman <mbreizma@redhat.com>
Tue, 23 May 2023 13:20:51 +0000 (13:20 +0000)
Make ptr nullable and add necessary operators.

Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
(cherry picked from commit f96ae0b367825c0e4433a57a086e03f75b1eab2e)

src/crimson/common/local_shared_foreign_ptr.h

index ca4edd4d37a3bb468738e13665969fe213fb02cd..c4bd1099a029590628b6344b1f51292d83516bfd 100644 (file)
@@ -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<PtrType> &&fptr)
-    : ptr(seastar::make_lw_shared(std::move(fptr))) {}
+    : ptr(fptr ? seastar::make_lw_shared(std::move(fptr)) : nullptr) {
+    assert(!ptr || (ptr && *ptr));
+  }
 
   template <typename T>
   friend local_shared_foreign_ptr<T> 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<seastar::foreign_ptr<PtrType>> get_foreign() {
-    return ptr->copy();
+  seastar::future<seastar::foreign_ptr<PtrType>> get_foreign() const noexcept {
+    assert(!ptr || (ptr && *ptr));
+    return ptr ? ptr->copy() :
+           seastar::make_ready_future<seastar::foreign_ptr<PtrType>>(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<T> make_local_shared_foreign(
 template <typename T>
 local_shared_foreign_ptr<T> make_local_shared_foreign(T &&ptr) {
   return make_local_shared_foreign<T>(
-    seastar::make_foreign(std::forward<T>(ptr)));
+    ptr ? seastar::make_foreign(std::forward<T>(ptr)) : nullptr);
+}
+
+template <typename T, typename U>
+inline bool operator==(const local_shared_foreign_ptr<T> &x,
+                       const local_shared_foreign_ptr<U> &y) {
+  return x.get() == y.get();
+}
+
+template <typename T>
+inline bool operator==(const local_shared_foreign_ptr<T> &x, std::nullptr_t) {
+  return x.get() == nullptr;
+}
+
+template <typename T>
+inline bool operator==(std::nullptr_t, const local_shared_foreign_ptr<T>& y) {
+  return nullptr == y.get();
+}
+
+template <typename T, typename U>
+inline bool operator!=(const local_shared_foreign_ptr<T> &x,
+                       const local_shared_foreign_ptr<U> &y) {
+  return x.get() != y.get();
+}
+
+template <typename T>
+inline bool operator!=(const local_shared_foreign_ptr<T> &x, std::nullptr_t) {
+  return x.get() != nullptr;
+}
+
+template <typename T>
+inline bool operator!=(std::nullptr_t, const local_shared_foreign_ptr<T>& y) {
+  return nullptr != y.get();
+}
+
+template <typename T, typename U>
+inline bool operator<(const local_shared_foreign_ptr<T> &x,
+                      const local_shared_foreign_ptr<U> &y) {
+  return x.get() < y.get();
+}
+
+template <typename T>
+inline bool operator<(const local_shared_foreign_ptr<T> &x, std::nullptr_t) {
+  return x.get() < nullptr;
+}
+
+template <typename T>
+inline bool operator<(std::nullptr_t, const local_shared_foreign_ptr<T>& y) {
+  return nullptr < y.get();
 }
 
+template <typename T, typename U>
+inline bool operator<=(const local_shared_foreign_ptr<T> &x,
+                       const local_shared_foreign_ptr<U> &y) {
+  return x.get() <= y.get();
+}
+
+template <typename T>
+inline bool operator<=(const local_shared_foreign_ptr<T> &x, std::nullptr_t) {
+  return x.get() <= nullptr;
+}
+
+template <typename T>
+inline bool operator<=(std::nullptr_t, const local_shared_foreign_ptr<T>& y) {
+  return nullptr <= y.get();
+}
+
+template <typename T, typename U>
+inline bool operator>(const local_shared_foreign_ptr<T> &x,
+                      const local_shared_foreign_ptr<U> &y) {
+  return x.get() > y.get();
+}
+
+template <typename T>
+inline bool operator>(const local_shared_foreign_ptr<T> &x, std::nullptr_t) {
+  return x.get() > nullptr;
+}
+
+template <typename T>
+inline bool operator>(std::nullptr_t, const local_shared_foreign_ptr<T>& y) {
+  return nullptr > y.get();
+}
+
+template <typename T, typename U>
+inline bool operator>=(const local_shared_foreign_ptr<T> &x,
+                       const local_shared_foreign_ptr<U> &y) {
+  return x.get() >= y.get();
+}
+
+template <typename T>
+inline bool operator>=(const local_shared_foreign_ptr<T> &x, std::nullptr_t) {
+  return x.get() >= nullptr;
+}
+
+template <typename T>
+inline bool operator>=(std::nullptr_t, const local_shared_foreign_ptr<T>& y) {
+  return nullptr >= y.get();
+}
+
+}
+
+namespace std {
+
+template <typename T>
+struct hash<crimson::local_shared_foreign_ptr<T>>
+    : private hash<typename std::pointer_traits<T>::element_type *> {
+  size_t operator()(const crimson::local_shared_foreign_ptr<T>& p) const {
+    return hash<typename std::pointer_traits<T>::element_type *>::operator()(p.get());
+  }
+};
+
 }
 
 namespace seastar {