Re: [asio-users] independent io services?
Brought to you by:
chris_kohlhoff
From: Christopher K. <ch...@ko...> - 2006-09-14 13:57:19
|
Hi Charlls, Charlls Quarra <cha...@ya...> wrote: > I'm wondering how efficient/stable/supported is to add > additional io_services for each independent group of ports i > want to listen. The idea is that eventually i could do > io_service::run_one on the desired io_service, without having > to process messages that go into ports i'm not interested > right now. But i don't know how overkill would be to have a > separate io_service for each of these interest groups. Is > there a more clever way around this? That sounds feasible to me. There's nothing wrong with having multiple io_service objects in a single program, and in fact it is intended to support program partioning in more or less the way you describe. An alternative which will be available in the next release of asio is the handler invocation hook. This lets you customise the way a handler is to be called. For example, you might use the following code to put all ready handlers into a queue: class handler_queue { public: void enqueue(const function<void()>& f) { queue_.push(f); } void run_all() { while (!queue_.empty()) { function<void()> f = queue_.front(); queue_.pop(); f(); } } private: std::queue<function<void()> > queue_; }; template<typename Handler> class queued_handler_t { public: queued_handler_t(handler_queue& q, Handler h) : queue_(q), handler_(h) {} void operator()() { handler_(); } template<typename Arg1> void operator()(Arg1 a1) { handler_(a1); } template<typename Arg1, typename Arg2> void operator()(Arg1 a1, Arg2 a2) { handler_(a1, a2); } private: handler_queue& queue_; Handler handler_: // Here is the handler invocation hook. Instead of calling // the function object f immediately (which is the default // behaviour), the function is put on the queue. template<typename Function> friend void asio_handler_invoke( Function f, queued_handler_t* h) { h->queue_.enqueue(f); } }; template<typename Handler> queued_handler_t<Handler> enqueue_to( handler_queue& q, Handler h) { return queued_handler_t<Handler>(q, h); } You would then use it like this: handler_queue q1; handler_queue q2; ... sock1.async_receive(buffers1, enqueue_to(q1, boost::bind(...))); sock2.async_receive(buffers2, enqueue_to(q2, boost::bind(...))); ... io_service.poll(); // Run everything that's ready to go. q1.run_all(); // Run handlers for q1, but not q2. I haven't compiled or tested the code above at all, but hopefully it gives the overall idea. Cheers, Chris |