int ActivePyModule::load(ActivePyModules *py_modules)
{
assert(py_modules);
- Gil gil(pMyThreadState);
+ Gil gil(pMyThreadState, true);
// We tell the module how we name it, so that it can be consistent
// with us in logging etc.
{
assert(pClassInstance != nullptr);
- Gil gil(pMyThreadState);
+ Gil gil(pMyThreadState, true);
// Execute
auto pValue = PyObject_CallMethod(pClassInstance,
{
assert(pClassInstance != nullptr);
- Gil gil(pMyThreadState);
+ Gil gil(pMyThreadState, true);
// Construct python-ized LogEntry
PyFormatter f;
assert(ss != nullptr);
assert(ds != nullptr);
- Gil gil(pMyThreadState);
+ Gil gil(pMyThreadState, true);
PyFormatter f;
cmdmap_dump(cmdmap, &f);
public:
ActivePyModule(const std::string &module_name_,
PyObject *pClass_,
- PyThreadState *my_ts_)
+ const SafeThreadState &my_ts_)
: PyModuleRunner(module_name_, pClass_, my_ts_)
{}
}
int ActivePyModules::start_one(std::string const &module_name,
- PyObject *pClass, PyThreadState *pMyThreadState)
+ PyObject *pClass, const SafeThreadState &pMyThreadState)
{
Mutex::Locker l(lock);
int start_one(std::string const &module_name,
PyObject *pClass,
- PyThreadState *pMyThreadState);
+ const SafeThreadState &pMyThreadState);
void dump_server(const std::string &hostname,
const DaemonStateCollection &dmc,
// Drop the GIL and remember the main thread state (current
// thread state becomes NULL)
pMainThreadState = PyEval_SaveThread();
+ assert(pMainThreadState != nullptr);
std::list<std::string> failed_modules;
// Configure sub-interpreter and construct C++-generated python classes
{
- Gil gil(pMainThreadState);
-
- pMyThreadState = Py_NewInterpreter();
+ SafeThreadState sts(pMainThreadState);
+ Gil gil(sts);
- if (pMyThreadState == nullptr) {
+ auto thread_state = Py_NewInterpreter();
+ if (thread_state == nullptr) {
derr << "Failed to create python sub-interpreter for '" << module_name << '"' << dendl;
return -EINVAL;
} else {
+ pMyThreadState.set(thread_state);
// Some python modules do not cope with an unpopulated argv, so lets
// fake one. This step also picks up site-packages into sys.path.
const char *argv[] = {"ceph-mgr"};
return 0;
}
+PyModule::~PyModule()
+{
+ if (pMyThreadState.ts != nullptr) {
+ Gil gil(pMyThreadState, true);
+ Py_XDECREF(pClass);
+ Py_XDECREF(pStandbyClass);
+ }
+}
+
void PyModuleRegistry::standby_start(MonClient *monc)
{
Mutex::Locker l(lock);
std::string get_site_packages();
public:
- PyThreadState *pMyThreadState = nullptr;
+ SafeThreadState pMyThreadState;
PyObject *pClass = nullptr;
PyObject *pStandbyClass = nullptr;
{
}
+ ~PyModule();
+
int load(PyThreadState *pMainThreadState);
std::string get_name() const {
std::unique_ptr<ActivePyModules> active_modules;
std::unique_ptr<StandbyPyModules> standby_modules;
- PyThreadState *pMainThreadState = nullptr;
+ PyThreadState *pMainThreadState;
// We have our own copy of MgrMap, because we are constructed
// before ClusterState exists.
{
assert(pClassInstance != nullptr);
- Gil gil(pMyThreadState);
+ Gil gil(pMyThreadState, true);
auto pValue = PyObject_CallMethod(pClassInstance,
const_cast<char*>("shutdown"), nullptr);
PyModuleRunner(
const std::string &module_name_,
PyObject *pClass_,
- PyThreadState *pMyThreadState_)
+ const SafeThreadState &pMyThreadState_)
:
module_name(module_name_),
pClass(pClass_), pMyThreadState(pMyThreadState_),
thread(this)
{
assert(pClass != nullptr);
- assert(pMyThreadState != nullptr);
+ assert(pMyThreadState.ts != nullptr);
assert(!module_name.empty());
}
}
int StandbyPyModules::start_one(std::string const &module_name,
- PyObject *pClass, PyThreadState *pMyThreadState)
+ PyObject *pClass, const SafeThreadState &pMyThreadState)
{
Mutex::Locker l(lock);
int StandbyPyModule::load()
{
- Gil gil(pMyThreadState);
+ Gil gil(pMyThreadState, true);
// We tell the module how we name it, so that it can be consistent
// with us in logging etc.
#include "common/Thread.h"
#include "common/Mutex.h"
+#include "mgr/Gil.h"
#include "mon/MonClient.h"
#include "mon/MgrMap.h"
#include "mgr/PyModuleRunner.h"
StandbyPyModuleState &state_,
const std::string &module_name_,
PyObject *pClass_,
- PyThreadState *pMyThreadState_)
+ const SafeThreadState &pMyThreadState_)
:
PyModuleRunner(module_name_, pClass_, pMyThreadState_),
state(state_)
int start_one(std::string const &module_name,
PyObject *pClass,
- PyThreadState *pMyThreadState);
+ const SafeThreadState &pMyThreadState);
void shutdown();