|
Boost Users : |
Subject: Re: [Boost-users] [asio] Async (or sync) in threads
From: Michael Powell (mwpowellhtx_at_[hidden])
Date: 2013-07-26 20:03:27
Okay, something has obviously changed from 1.53. Which means my
comprehension/usage needs to get educated. How do I know? Glad you
asked.
I had a UDP beacon building and working under 1.53, but which when I
take that and run it under 1.54, now fails with a bad file descriptor
exception.
terminate called after throwing an instance of
'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error>
>'
what(): assign: Bad file descriptor
Aborted
As per my usage, not a clue. Maybe I need to be specifying some
precompiler definition or something.
Are there any potential snags? Like a dependency on date/time,
threads, something like that, I should be aware of?
Possibly if I address that and get it working for the "simple" basic
UDP writer example I cobbled together, that also addresses the TCP
side of things.
On Thu, Jul 25, 2013 at 3:40 PM, Anthony Foiani <tkil_at_[hidden]> wrote:
> Michael Powell <mwpowellhtx_at_[hidden]> writes:
>
>> On Thu, Jul 25, 2013 at 2:30 AM, Anthony Foiani <tkil_at_[hidden]> 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#thread.thread_management.tutorial.interruption
> (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
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net