Skip to content

Commit

Permalink
Control the lifetime of the bp::object that commands are extracted fr…
Browse files Browse the repository at this point in the history
…om so it's deletion can be wrapped in a GIL lock.
  • Loading branch information
apathyboy committed Mar 29, 2013
1 parent 5a4d196 commit 6763c9e
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions src/swganh_core/command/python_command_creator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,18 @@ std::shared_ptr<CommandInterface> PythonCommandCreator::operator() (
}
#endif

auto new_instance = command_module_.attr(class_name_.c_str())(bp::ptr(kernel), boost::ref(properties));
// Create an instance of the python class and store it in a shared pointer
// so it's deletion can be properly wrapped in a GIL lock
std::shared_ptr<bp::object> new_instance = std::shared_ptr<bp::object>(
new bp::object(command_module_.attr(class_name_.c_str())(bp::ptr(kernel), boost::ref(properties))),
[] (bp::object* obj) { ScopedGilLock lock; delete obj; });

if (!new_instance.is_none())
if (!new_instance->is_none())
{
CommandInterface* obj_pointer = bp::extract<CommandInterface*>(new_instance);
// Extract the C++ base pointer from the python object and store both in a shared pointer
// to ensure there are no lifetime issues (if the bp::object goes out of scope the interface
// pointer is invalidated)
CommandInterface* obj_pointer = bp::extract<CommandInterface*>(*new_instance);
command.reset(obj_pointer, [new_instance] (CommandInterface*) {});
command->SetCommandProperties(properties);
}
Expand Down

0 comments on commit 6763c9e

Please sign in to comment.