Kirell
Kirell

Reputation: 9818

Boost Asio - How to know when the handler queue is empty?

I am currently posting handlers to my io_service and execute them in a thread pool.

io_serv.post( boost::bind(&Class::bar, p1, p2) );

My workers run this function:

m_mutex.lock();
std::cout << "[" << boost::this_thread::get_id()
        << "] Thread Start" << std::endl;
m_mutex.unlock();

size_t tasks = m_serv.run();

m_mutex.lock();
std::cout << "[" << boost::this_thread::get_id() << "] accomplished "
          << tasks << " tasks" << std::endl;
m_mutex.unlock();

So far so good but now I want to trigger an event when the handler queue is empty without killing my active (but waiting) threads.

Is it possible and how ?

Upvotes: 3

Views: 4362

Answers (1)

Galimov Albert
Galimov Albert

Reputation: 7357

First time i see using of asio as a queue dispatcher. Not bad technique i think.

Well, i suggest you are running io_service::run to serve the handlers. As documentation says, run will block until io_service is stopped OR all work has finished. So you can run your "empty queue event" after io_service::run:

while( !finished ) {
    io_serv.run();
    io_serv.reset();
    io_serv.post( boost::bind(&Class::fill_queue, instance) );
}

This in case you have no other asio activity on this io_service and you not using io_service::work.

As mentioned in comments you using io_service::work so plan A failed(it will not work since this class prevents exitting on empty queue). Well, you can do io_serv.post() after each bunch of io_serv.post()-s for thread jobs. The handler can contain waiting with boost::condition while other threads finish their work. As you do post() for this after actual jobs, i think asio will call it after dispatching all jobs, but its subject for investigation. Anyway that handler can re-post() himself to free current thread if condition is not ready yet.

But i think easiest way is to replace io_service::work with equialent while construct.

Upvotes: 3

Related Questions