| 807 | } |
| 808 | |
| 809 | void container::impl::run(int threads) { |
| 810 | // Have to "manually" generate container events |
| 811 | CALL_ONCE(start_once_, &impl::start_event, this); |
| 812 | |
| 813 | // Run handler threads |
| 814 | threads = std::max(threads, 1); // Ensure at least 1 thread |
| 815 | typedef std::vector<std::thread*> vt; // pointer vector to work around failures in older compilers |
| 816 | vt ts(threads-1); |
| 817 | for (vt::iterator i = ts.begin(); i != ts.end(); ++i) { |
| 818 | *i = new std::thread(&impl::thread, this); |
| 819 | } |
| 820 | |
| 821 | thread(); // Use this thread too. |
| 822 | |
| 823 | // Wait for the other threads to stop |
| 824 | for (vt::iterator i = ts.begin(); i != ts.end(); ++i) { |
| 825 | (*i)->join(); |
| 826 | delete *i; |
| 827 | } |
| 828 | |
| 829 | bool last = false; |
| 830 | { |
| 831 | GUARD(lock_); |
| 832 | last = threads_==0; |
| 833 | } |
| 834 | if (last) CALL_ONCE(stop_once_, &impl::stop_event, this); |
| 835 | |
| 836 | // Throw an exception if we disconnected the proactor because of an exception |
| 837 | { |
| 838 | GUARD(lock_); |
| 839 | if (!disconnect_error_.empty()) throw proton::error(disconnect_error_.description()); |
| 840 | }; |
| 841 | } |
| 842 | |
| 843 | void container::impl::auto_stop(bool set) { |
| 844 | GUARD(lock_); |