recursive boost exception using io_service


I was expecting the code below to continue throwing an exception, since a call to the ios object is performed within the exception handling function thus making it recursive.

In addition, I thought that the worker.reset() function would allow for threads to complete before stopping the io_service object. In which case, the recursive exception handler should be calling itself infinity and the program should never end.

But somehow the program finishes. Why is that ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <mutex>
#include <thread>
#include <iostream>

std::mutex mx;

void work_thread(boost::shared_ptr<boost::asio::io_service> ios, int cnt) {

  //Ensure lock each time a cout is performed
  mx.lock();
  std::cout << "Thread " << cnt << " Start.\n";
  mx.unlock();

  try {
    ios->run();
  }
  catch (std::exception & ex) {
    mx.lock();
    std::cout << "Error: " << ex.what() << ".\n";
    mx.unlock();
  }
  
  mx.lock();
  std::cout << "Thread " << cnt << " End.\n";
  mx.unlock();
}

void throw_exception(boost::shared_ptr<boost::asio::io_service> ios) {
  mx.lock();
  std::cout << "Throw Err\n" ;
  mx.unlock();
  ios->post(boost::bind(&throw_exception, ios));
  throw(std::runtime_error("ERROR"));
}

void print_number(int number) {
  std::cout << "Number: " << number << std::endl;
}

int main(void) {
  
  boost::shared_ptr<boost::asio::io_service> ios (new boost::asio::io_service);
  boost::shared_ptr<boost::asio::io_service::work> worker (new boost::asio::io_service::work(*ios));

  mx.lock();
  std::cout << "Program exits when all work has completed.\n";
  mx.unlock();

  boost::thread_group threads;
  for(int i=1; i<4; i++)
    threads.create_thread(boost::bind(&work_thread, ios, i));

  std::this_thread::sleep_for(std::chrono::seconds(2));

  ios->post(boost::bind(&throw_exception, ios));

  worker.reset();
  threads.join_all();

  return 0;
}
Last edited on
Topic archived. No new replies allowed.