CARLA
PythonUtil.h
Go to the documentation of this file.
1 // Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
2 // de Barcelona (UAB).
3 //
4 // This work is licensed under the terms of the MIT license.
5 // For a copy, see <https://opensource.org/licenses/MIT>.
6 
7 #pragma once
8 
9 #include "carla/NonCopyable.h"
10 
11 #ifdef LIBCARLA_WITH_PYTHON_SUPPORT
12 # if defined(__clang__)
13 # pragma clang diagnostic push
14 # pragma clang diagnostic ignored "-Wdeprecated-register"
15 # endif
16 # include <boost/python.hpp>
17 # if defined(__clang__)
18 # pragma clang diagnostic pop
19 # endif
20 #endif // LIBCARLA_WITH_PYTHON_SUPPORT
21 
22 namespace carla {
23 
24  class PythonUtil {
25  public:
26 
27  static bool ThisThreadHasTheGIL() {
28 #ifdef LIBCARLA_WITH_PYTHON_SUPPORT
29 # if PY_MAJOR_VERSION >= 3
30  return PyGILState_Check();
31 # else
32  PyThreadState *tstate = _PyThreadState_Current;
33  return (tstate != nullptr) && (tstate == PyGILState_GetThisThreadState());
34 # endif // PYTHON3
35 #else
36  return false;
37 #endif // LIBCARLA_WITH_PYTHON_SUPPORT
38  }
39 
40 #ifdef LIBCARLA_WITH_PYTHON_SUPPORT
41 
42  /// Acquires a lock on the Python's Global Interpreter Lock, necessary for
43  /// calling Python code from a different thread.
44  class AcquireGIL : private NonCopyable {
45  public:
46 
47  AcquireGIL() : _state(PyGILState_Ensure()) {}
48 
49  ~AcquireGIL() {
50  PyGILState_Release(_state);
51  }
52 
53  private:
54 
55  PyGILState_STATE _state;
56  };
57 
58  /// Releases the lock on the Python's Global Interpreter Lock, use it when doing
59  /// blocking I/O operations.
60  class ReleaseGIL : private NonCopyable {
61  public:
62 
63  ReleaseGIL() : _state(PyEval_SaveThread()) {}
64 
65  ~ReleaseGIL() {
66  PyEval_RestoreThread(_state);
67  }
68 
69  private:
70 
71  PyThreadState *_state;
72  };
73 
74 #else // LIBCARLA_WITH_PYTHON_SUPPORT
75 
76  class AcquireGIL : private NonCopyable {};
77  class ReleaseGIL : private NonCopyable {};
78 
79 #endif // LIBCARLA_WITH_PYTHON_SUPPORT
80 
81  /// A deleter that can be passed to a smart pointer to acquire the GIL
82  /// before destroying the object.
84  public:
85 
86  template <typename T>
87  void operator()(T *ptr) const {
88 #ifdef LIBCARLA_WITH_PYTHON_SUPPORT
89  if (ptr != nullptr && !PythonUtil::ThisThreadHasTheGIL()) {
90  AcquireGIL lock;
91  delete ptr;
92  } else
93 #endif // LIBCARLA_WITH_PYTHON_SUPPORT
94  delete ptr;
95  }
96  };
97 
98  /// A deleter that can be passed to a smart pointer to release the GIL
99  /// before destroying the object.
101  public:
102 
103  template <typename T>
104  void operator()(T *ptr) const {
105 #ifdef LIBCARLA_WITH_PYTHON_SUPPORT
106  if (ptr != nullptr && PythonUtil::ThisThreadHasTheGIL()) {
107  ReleaseGIL lock;
108  delete ptr;
109  } else
110 #endif // LIBCARLA_WITH_PYTHON_SUPPORT
111  delete ptr;
112  }
113  };
114  };
115 
116 } // namespace carla
A deleter that can be passed to a smart pointer to acquire the GIL before destroying the object...
Definition: PythonUtil.h:83
A deleter that can be passed to a smart pointer to release the GIL before destroying the object...
Definition: PythonUtil.h:100
This file contains definitions of common data structures used in traffic manager. ...
Definition: Carla.cpp:133
static bool ThisThreadHasTheGIL()
Definition: PythonUtil.h:27
Inherit (privately) to suppress copy/move construction and assignment.