mgr: update for SafeThreadState

A bunch of the previous commits were done
before this class existed, so updating in
one go instead of trying to edit history
in fine detail.

Signed-off-by: John Spray <john.spray@redhat.com>
This commit is contained in:
John Spray 2017-10-16 10:51:34 -04:00
parent 7e61f79f5d
commit 29193a47e6
10 changed files with 34 additions and 20 deletions

View File

@ -54,7 +54,7 @@ std::string handle_pyerror()
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.
@ -82,7 +82,7 @@ void ActivePyModule::notify(const std::string &notify_type, const std::string &n
{
assert(pClassInstance != nullptr);
Gil gil(pMyThreadState);
Gil gil(pMyThreadState, true);
// Execute
auto pValue = PyObject_CallMethod(pClassInstance,
@ -105,7 +105,7 @@ void ActivePyModule::notify_clog(const LogEntry &log_entry)
{
assert(pClassInstance != nullptr);
Gil gil(pMyThreadState);
Gil gil(pMyThreadState, true);
// Construct python-ized LogEntry
PyFormatter f;
@ -187,7 +187,7 @@ int ActivePyModule::handle_command(
assert(ss != nullptr);
assert(ds != nullptr);
Gil gil(pMyThreadState);
Gil gil(pMyThreadState, true);
PyFormatter f;
cmdmap_dump(cmdmap, &f);

View File

@ -60,7 +60,7 @@ private:
public:
ActivePyModule(const std::string &module_name_,
PyObject *pClass_,
PyThreadState *my_ts_)
const SafeThreadState &my_ts_)
: PyModuleRunner(module_name_, pClass_, my_ts_)
{}

View File

@ -322,7 +322,7 @@ PyObject *ActivePyModules::get_python(const std::string &what)
}
int ActivePyModules::start_one(std::string const &module_name,
PyObject *pClass, PyThreadState *pMyThreadState)
PyObject *pClass, const SafeThreadState &pMyThreadState)
{
Mutex::Locker l(lock);

View File

@ -110,7 +110,7 @@ public:
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,

View File

@ -155,6 +155,7 @@ int PyModuleRegistry::init(const MgrMap &map)
// 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;
@ -191,14 +192,15 @@ int PyModule::load(PyThreadState *pMainThreadState)
// Configure sub-interpreter and construct C++-generated python classes
{
Gil gil(pMainThreadState);
SafeThreadState sts(pMainThreadState);
Gil gil(sts);
pMyThreadState = Py_NewInterpreter();
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"};
@ -289,6 +291,15 @@ int PyModule::load(PyThreadState *pMainThreadState)
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);

View File

@ -33,7 +33,7 @@ private:
std::string get_site_packages();
public:
PyThreadState *pMyThreadState = nullptr;
SafeThreadState pMyThreadState;
PyObject *pClass = nullptr;
PyObject *pStandbyClass = nullptr;
@ -42,6 +42,8 @@ public:
{
}
~PyModule();
int load(PyThreadState *pMainThreadState);
std::string get_name() const {
@ -68,7 +70,7 @@ private:
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.

View File

@ -66,7 +66,7 @@ void PyModuleRunner::shutdown()
{
assert(pClassInstance != nullptr);
Gil gil(pMyThreadState);
Gil gil(pMyThreadState, true);
auto pValue = PyObject_CallMethod(pClassInstance,
const_cast<char*>("shutdown"), nullptr);

View File

@ -55,14 +55,14 @@ public:
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());
}

View File

@ -77,7 +77,7 @@ void StandbyPyModules::shutdown()
}
int StandbyPyModules::start_one(std::string const &module_name,
PyObject *pClass, PyThreadState *pMyThreadState)
PyObject *pClass, const SafeThreadState &pMyThreadState)
{
Mutex::Locker l(lock);
@ -108,7 +108,7 @@ int StandbyPyModules::start_one(std::string const &module_name,
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.

View File

@ -21,6 +21,7 @@
#include "common/Thread.h"
#include "common/Mutex.h"
#include "mgr/Gil.h"
#include "mon/MonClient.h"
#include "mon/MgrMap.h"
#include "mgr/PyModuleRunner.h"
@ -90,7 +91,7 @@ class StandbyPyModule : public PyModuleRunner
StandbyPyModuleState &state_,
const std::string &module_name_,
PyObject *pClass_,
PyThreadState *pMyThreadState_)
const SafeThreadState &pMyThreadState_)
:
PyModuleRunner(module_name_, pClass_, pMyThreadState_),
state(state_)
@ -136,7 +137,7 @@ public:
int start_one(std::string const &module_name,
PyObject *pClass,
PyThreadState *pMyThreadState);
const SafeThreadState &pMyThreadState);
void shutdown();