]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr: move GIL helpers to Gil.{h,cc}
authorKefu Chai <kchai@redhat.com>
Thu, 18 Feb 2021 04:11:24 +0000 (12:11 +0800)
committerKefu Chai <kchai@redhat.com>
Mon, 22 Feb 2021 11:49:08 +0000 (19:49 +0800)
Signed-off-by: Kefu Chai <kchai@redhat.com>
src/mgr/ActivePyModules.cc
src/mgr/Gil.cc
src/mgr/Gil.h

index e20241eb99c2e2e3e04dbd4a044624ff4f9a3fff..e10546c20502c987553a3abec007b1f87678b445 100644 (file)
@@ -63,67 +63,6 @@ ActivePyModules::ActivePyModules(
 
 ActivePyModules::~ActivePyModules() = default;
 
-namespace {
-  // because the Python runtime could relinquish the GIL when performing GC
-  // and re-acquire it afterwards, we should enforce following locking policy:
-  // 1. do not acquire locks when holding the GIL, use a without_gil or
-  //    without_gil_t to guard the code which acquires non-gil locks.
-  // 2. always hold a GIL when calling python functions, for example, when
-  //    constructing a PyFormatter instance.
-  //
-  // a wrapper that provides a convenient RAII-style mechinary for acquiring
-  // and releasing GIL, like the macros of Py_BEGIN_ALLOW_THREADS and
-  // Py_END_ALLOW_THREADS.
-  struct without_gil_t {
-    without_gil_t()
-    {
-      assert(PyGILState_Check());
-      release_gil();
-    }
-    ~without_gil_t()
-    {
-      if (save) {
-        acquire_gil();
-      }
-    }
-  private:
-    void release_gil() {
-      save = PyEval_SaveThread();
-    }
-    void acquire_gil() {
-      assert(save);
-      PyEval_RestoreThread(save);
-      save = nullptr;
-    }
-    PyThreadState *save = nullptr;
-    friend struct with_gil_t;
-  };
-  struct with_gil_t {
-    with_gil_t(without_gil_t& allow_threads)
-      : allow_threads{allow_threads}
-    {
-      allow_threads.acquire_gil();
-    }
-    ~with_gil_t() {
-      allow_threads.release_gil();
-    }
-  private:
-    without_gil_t& allow_threads;
-  };
-  // invoke func with GIL acquired
-  template<typename Func>
-  auto with_gil(without_gil_t& no_gil, Func&& func)
-  {
-    with_gil_t gil{no_gil};
-    return std::invoke(std::forward<Func>(func));
-  }
-  template<typename Func>
-  auto without_gil(Func&& func) {
-    without_gil_t no_gil;
-    return std::invoke(std::forward<Func>(func));
-  }
-}
-
 void ActivePyModules::dump_server(const std::string &hostname,
                       const DaemonStateCollection &dmc,
                       Formatter *f)
index d476c7177fb15786f049d863366ca9792f486c75..de27b9acd666b40497118b014ffd67f1eab8c9d7 100644 (file)
@@ -77,3 +77,38 @@ Gil::~Gil()
   dout(25) << "GIL released for thread state " << pThreadState.ts << dendl;
 }
 
+without_gil_t::without_gil_t()
+{
+  assert(PyGILState_Check());
+  release_gil();
+}
+
+without_gil_t::~without_gil_t()
+{
+  if (save) {
+    acquire_gil();
+  }
+}
+
+void without_gil_t::release_gil()
+{
+  save = PyEval_SaveThread();
+}
+
+void without_gil_t::acquire_gil()
+{
+  assert(save);
+  PyEval_RestoreThread(save);
+  save = nullptr;
+}
+
+with_gil_t::with_gil_t(without_gil_t& allow_threads)
+  : allow_threads{allow_threads}
+{
+  allow_threads.acquire_gil();
+}
+
+with_gil_t::~with_gil_t()
+{
+  allow_threads.release_gil();
+}
index bff2d23329e6d6483c0bb4cbd0580540755e6cf8..ffade120fd37d44a3769602d307b913af209613b 100644 (file)
@@ -14,6 +14,9 @@
 
 #pragma once
 
+#include <cassert>
+#include <functional>
+
 struct _ts;
 typedef struct _ts PyThreadState;
 
@@ -70,3 +73,42 @@ private:
   PyThreadState *pNewThreadState = nullptr;
 };
 
+// because the Python runtime could relinquish the GIL when performing GC
+// and re-acquire it afterwards, we should enforce following locking policy:
+// 1. do not acquire locks when holding the GIL, use a without_gil or
+//    without_gil_t to guard the code which acquires non-gil locks.
+// 2. always hold a GIL when calling python functions, for example, when
+//    constructing a PyFormatter instance.
+//
+// a wrapper that provides a convenient RAII-style mechinary for acquiring
+// and releasing GIL, like the macros of Py_BEGIN_ALLOW_THREADS and
+// Py_END_ALLOW_THREADS.
+struct without_gil_t {
+  without_gil_t();
+  ~without_gil_t();
+private:
+  void release_gil();
+  void acquire_gil();
+  PyThreadState *save = nullptr;
+  friend struct with_gil_t;
+};
+
+struct with_gil_t {
+  with_gil_t(without_gil_t& allow_threads);
+  ~with_gil_t();
+private:
+  without_gil_t& allow_threads;
+};
+
+// invoke func with GIL acquired
+template<typename Func>
+auto with_gil(without_gil_t& no_gil, Func&& func) {
+  with_gil_t gil{no_gil};
+  return std::invoke(std::forward<Func>(func));
+}
+
+template<typename Func>
+auto without_gil(Func&& func) {
+  without_gil_t no_gil;
+  return std::invoke(std::forward<Func>(func));
+}