]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
common, crypto: give names to OpenSSL's mutexes.
authorRadoslaw Zarzynski <rzarzyns@redhat.com>
Fri, 12 Jul 2019 13:44:38 +0000 (09:44 -0400)
committerRadoslaw Zarzynski <rzarzyns@redhat.com>
Mon, 15 Jul 2019 14:53:45 +0000 (10:53 -0400)
Fixes: http://tracker.ceph.com/issues/40698
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
src/common/ceph_crypto.cc
src/common/ceph_mutex.h
src/common/containers.h

index f63f39a3bbdbbafad290001b8a4c76073c492181..b89632c00c2e954f43fd5a7ced1c51cb29f92040 100644 (file)
@@ -32,9 +32,13 @@ namespace ceph::crypto::ssl {
 #if OPENSSL_VERSION_NUMBER < 0x10100000L
 static std::atomic_uint32_t crypto_refs;
 
-static std::vector<ceph::shared_mutex> ssl_mutexes {
-  static_cast<size_t>(std::max(CRYPTO_num_locks(), 0))
-};
+
+static auto ssl_mutexes = ceph::make_lock_container<ceph::shared_mutex>(
+  static_cast<size_t>(std::max(CRYPTO_num_locks(), 0)),
+  [](const size_t i) {
+    return ceph::make_shared_mutex(
+      std::string("ssl-mutex-") + std::to_string(i));
+  });
 
 static struct {
   // we could use e.g. unordered_set instead at the price of providing
index 13667870eef7dde474d1a94f05c5d44c4dad1ddd..5f340561eb2386f77aff756fa6e668f113823d2b 100644 (file)
@@ -3,6 +3,9 @@
 
 #pragma once
 
+#include <utility>
+#include "common/containers.h"
+
 // What and why
 // ============
 //
@@ -44,6 +47,11 @@ namespace ceph {
     return {};
   }
 
+  template <typename ...Args>
+  shared_mutex make_shared_mutex(Args&& ...args) {
+    return {};
+  }
+
   #define ceph_mutex_is_locked(m) true
   #define ceph_mutex_is_locked_by_me(m) true
 }
@@ -135,3 +143,21 @@ namespace ceph {
 #endif // CEPH_DEBUG_MUTEX
 
 #endif // WITH_SEASTAR
+
+namespace ceph {
+
+template <class LockT,
+          class LockFactoryT>
+ceph::containers::tiny_vector<LockT> make_lock_container(
+  const std::size_t num_instances,
+  LockFactoryT&& lock_factory)
+{
+  return {
+    num_instances, [&](const std::size_t i, auto emplacer) {
+      // this will be called `num_instances` times
+      new (emplacer.data()) LockT {lock_factory(i)};
+    }
+  };
+}
+} // namespace ceph
+
index a52f43f49d7a2d836c37ae07cb7fa18db7dca853..c0aa835445bb646419abba687fe11efd0c3b13fd 100644 (file)
@@ -53,7 +53,7 @@ namespace ceph::containers {
 //  4. std::unique_ptr<ValueT>: extra indirection together with memory
 //     fragmentation.
 
-template<typename Value, std::size_t InternalCapacity>
+template<typename Value, std::size_t InternalCapacity = 0>
 class tiny_vector {
   // NOTE: to avoid false sharing consider aligning to cache line
   using storage_unit_t = \
@@ -97,6 +97,17 @@ public:
   //     }
   //   }
   // ```
+  //
+  // For the sake of supporting the ceph::make_mutex() family of
+  // factories, which relies on C++17's guaranteed copy elision,
+  // the emplacer provides `data()` to retrieve the location for
+  // constructing the instance with placement-new. This is handy
+  // as the `emplace()` depends on perfect forwarding, and thus
+  // interfere with the elision for cases like:
+  // ```
+  //   emplacer.emplace(ceph::make_mutex("mtx-name"));
+  // ```
+  // See: https://stackoverflow.com/a/52498826
 
   class emplacer {
     friend class tiny_vector;
@@ -107,13 +118,17 @@ public:
     }
 
   public:
+    void* data() {
+      void* const ret = &parent->data[parent->_size++];
+      parent = nullptr;
+      return ret;
+    }
+
     template<class... Args>
     void emplace(Args&&... args) {
-      if (!parent) {
-        return;
+      if (parent) {
+        new (data()) Value(std::forward<Args>(args)...);
       }
-      new (&parent->data[parent->_size++]) Value(std::forward<Args>(args)...);
-      parent = nullptr;
     }
   };