Skip to content
Browse files

Control the lifetime of the bp::object that commands are extracted fr…

…om so it's deletion can be wrapped in a GIL lock.
  • Loading branch information...
1 parent 5a4d196 commit 6763c9ee96b4ae3c5434d1f342eb1eef6f706e39 @apathyboy apathyboy committed Mar 28, 2013
Showing with 10 additions and 3 deletions.
  1. +10 −3 src/swganh_core/command/python_command_creator.cc
View
13 src/swganh_core/command/python_command_creator.cc
@@ -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);
}

0 comments on commit 6763c9e

Please sign in to comment.
Something went wrong with that request. Please try again.