I am using Boost Python to expose a function that holds an internal thread, the class has start
and stop
functions that only control an internal loop. The code for MyClass
is:
class MyClass
{
private:
std::atomic<bool> running_;
std::thread worker_;
std::function<std::string(std::string)> m_op;
void printMessage()
{
std::string s = "hello";
while (running_)
{
s = m_op(s);
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
public:
MyClass() : running_(false) {}
MyClass(const std::function<std::string(std::string)>& op) : running_(false), m_op(op) {}
void start()
{
if (!running_)
{
running_ = true;
worker_ = std::thread(&MyClass::printMessage, this);
}
}
void stop()
{
if (running_)
{
running_ = false;
worker_.join();
}
}
};
I then create a helper function to pass a callback as:
template<class output_tp, class... input_tps>
struct function_helper
{
function_helper(const boost::python::object& op) : m_op(op) {}
output_tp operator()(input_tps&&... args)
{
return boost::python::call<output_tp>(m_op.ptr(), std::forward<input_tps>(args)...);
}
private:
boost::python::object m_op;
};
boost::shared_ptr<MyClass> makeMakeClass(const boost::python::object& obj)
{
return boost::make_shared<MyClass>(function_helper<std::string, std::string>(obj));
}
I then create my module:
BOOST_PYTHON_MODULE(draft)
{
using namespace boost::python;
class_<MyClass, bases<>, boost::shared_ptr<MyClass>, boost::noncopyable>("MyClass")
.def("__init__", make_constructor(makeMakeClass))
.def("start", &MyClass::start)
.def("stop", &MyClass::stop);
}
I use the draft
module in jupyter as follows attached
The first run causes a crash as in
The second run is not throwing but produces nothing. Could you please help me make this work.