2

I use a c++ class that encapsulates a boost::asio::io_service.

class IoService {
 public:
  static IoService& getInstance() {
    static IoService instance;
    return instance;
  }
  void start() {
    _ioServiceThread = std::thread(&IoService::run, this);
  }
  void stop() {
    _ioService.stop();
    _ioServiceThread.join();
  }
  void run() {
   _ioService.run();
  }

 private:
  IoService();
  ~IoService();
  IoService(const IoService& old) = delete;
  IoService(const IoService&& old) = delete;
  IoService& operator=(const IoService& old) = delete;
  IoService& operator=(const IoService&& old) = delete;

  boost::asio::io_service _ioService;
  std::thread _ioServiceThread;
};

But when I am calling the stop method, the program is crashing on the join:

terminate called after throwing an instance of 'std::system_error'
what():  Resource deadlock avoided
Aborted

What do you think ?

klaus
  • 754
  • 8
  • 28
  • Provide MCVE, io_services doesn't have `join` method. Show the code where IoService is created and how start/stop are called. And where is the body of IoService destructor? – rafix07 May 06 '19 at 15:52
  • My bad, it was a typo. I am calling join on the std thread ! – klaus May 06 '19 at 16:00

1 Answers1

6

That's the error that you get when a thread tries to join itself.

So it sounds like your problem is that you're calling the stop() method from a handler function that was invoked by the io_service.

caf
  • 233,326
  • 40
  • 323
  • 462
  • I’m not sure to understand... when I call the _ioService.stop() method, it looks like I’m not exiting the _ioService.run(); method. Is it expected ? Maybe it is why the joining is not working…? – klaus May 07 '19 at 07:33
  • The problem is the thread context which is calling `IoService::stop()`. You are calling it from a handler function, which means that it's being run by the thread that is running `io_service::run()`, which is the same thread you're trying to join. You need to call the `::stop()` function from a different thread. – caf May 07 '19 at 07:47
  • To be more clear on how I use the IoService class, I have two others classes A and B that have a private `IoService& _ioService;` and I call _ioService.stop() in A’s descructor. Is it bad ? – klaus May 07 '19 at 08:41
  • What matters is which thread runs it - so, which thread ends up running A's destructor? – caf May 08 '19 at 00:32