
Hi Andrew, --- Andrew Schweitzer <a.schweitzer.grps@gmail.com> wrote:
*Maybe there should be a "run_forever" version of demuxer::run?
If you want it to run forever just give it some "work": asio::demuxer d; asio::demuxer::work w(d); d.run(); In general you'll want to destroy the work object when you actually do want the demuxer to exit.
If I read the docs correctly, demuxer::run will exit if it has nothing left to do. So if the last timer expires, run will exit. The next time a timer is started demuxer::reset and demuxer::run must be called again or nothing will happen. Is this correct?
Yes. However, an application that is written to use an asynchronous approach will continue to start asynchronous operations (e.g. a server will always have an async_accept operation running).
Could this happen for sockets as well, if user never called a function like read or accept that will sit there forever until something happens? For example, if a client problem calls run, does an async connect, sends some data, but doesn't do a read, then would run stop after the send completed?
Yes.
Or would run wait for socket to be closed?
No.
*It looks like deadline_timer objects need to be dynamically allocated, right?
No, the deadline_timer object itself does not need to be dynamically allocated.
It looks to me that when they destruct they stop themselves.
The destructor implicitly cancels any outstanding asynchronous wait, yes. The handler for that wait operation is still dispatched.
I think this means that there are two dynamic allocations per timer started, one for the implementation and one for the "handle". Could this be avoided?
Yes, looking at the implementation again I can probably change it to eliminate the dynamic memory allocation of the handler as well.
*Since user must allocate each deadline_timer (assuming above correct), then user must remember to toss them when timer completes. It might be nice if this could be handled automatically.
Since you don't have to dynamically allocate the deadline_timer object this doesn't apply :)
*There aren't really unique IDs for timers, right? The address of the timer object must be unique as long as the timer is running, but after the timer completes it could be re-used for another timer, so that doesn't seem like a great idea.
This address is used internally as a cancellation token. Since the destruction of a deadline_timer automatically cancels the timer (and removes the token from the backend), it's not a problem if the address gets reused.
Does anyone else think unique timer IDs belong in the library? I'm not sure it's requirement, but most timer code I've worked on has used a unique ID. It's not hard for the application to provide this, but it is a bit more work.
What use case are you thinking of here? I have never had a need for a timer ID when instead I can use boost::bind to associate whatever data I need directly with the completion handler. Cheers, Chris