
Michael Powell
On Thu, Jul 25, 2013 at 2:30 AM, Anthony Foiani
wrote: Given that thread interruption is a bit dicey, you might consider doing the timeout work in the thread / io_service itself. That way, the controller only needs to launch the thread, then join it.
Not sure what you mean by dicey. If by dicey you mean that accept() blocks altogether, interrupt requests and all, then, yes, I'll agree dicey.
I only meant that boost thread interrupts are processed only at very specific times; I don't recall offhand if an ASIO synchronous accept would qualify. There's a list of them here: http://www.boost.org/doc/libs/1_54_0/doc/html/thread/thread_management.html#... (or: http://preview.tinyurl.com/p959dyz )
Obviously, this won't work either, because if a client never connects (which is a possibility when testing), then that can't hang up the rest of the app.
Can you be more specific? In the io_service itself?
The author of ASIO gave the basic pattern for implementing timeouts in his blog, let me find the link... http://blog.think-async.com/2010/04/timeouts-by-analogy.html The basic idea is that you start two asynchronous actions: 1. async accept (calls handler when a connection comes in). 2. timer (calls handler when timer expires). Note that the timer (2) doesn't have to be for the whole duration of the timeout; to use Chris's analogy, it's only how often you want to check the "parking meter", not the actual time on the meter itself. Now, in your accept handler, you cancel the timer (or at least reset the "parking meter" counter, so that the timer sees that you've "fed the meter".) In your timer handler, you check the meter; if it has expired, you cancel the accept operation. (These two operations should probably be done against the same io_service; if that io_service is being run by multiple threads, you will have to make sure to deal with synchronization issues. Easiest is probably to run an acceptor and its timer in a single strand.) I use exactly this pattern for read timeouts, and it works great.
Since you're catching exceptions *anyway*, don't bother with error codes unless you're detecting specific values (as you do for eof elsewhere).
I am, I believe, checking for bytes, are bytes available, this sort of thing. Instead of receive blocking when there is no data, which is one plausible use case.
The use above is checking the error code return from synchronous accept; that shouldn't indicate "bytes available", so much as "something went very wrong with the acceptor". That's why I was suggesting that you just use exceptions. Error codes from something like read_until can sometimes give you the information you want, but that's pretty rare. The typical ASIO style is to set things up so your code is "told" when there is data available, without needing to poll data sources.
As soon as I schedule an async_accept, I get a segmentation fault.
I don't know the inner workings of the io_service that well, but I suspect that may be because I have created the server outside the running thread.
Hm... so long as the execution context (in this case, the stack frame in which you allocated the server) is still active, then you should be fine. But if you exit that frame after creating it, then yes, that object has been destructed, and you're asking the io_service to run on garbage memory.
Something you mentioned earlier though, which is starting to click with me: io_service might be the thing I want to run and/or have time out, and just bypass needing to do anything with threads.
It's a little bit different than what I expected and/or am used to.
That kinda sums up the entire "learn to use ASIO" experience for me. :) Let us know if you manage to get the tutorial examples running, then we can work from there. Good luck! Best regards, Anthony Foiani