|
Boost Users : |
Subject: Re: [Boost-users] [asio] sync receive_from with timeout
From: Ovanes Markarian (om_boost_at_[hidden])
Date: 2009-03-04 04:56:21
Stephan,
I had to program smth similar. Than a tried some "non-standard" approach. If
you use boost threads to handle socket communication, when the socket is
blocked you can interrupt the thread which owns the socket. You will receive
the interruption exception and handle your socket cancel there. This is not
documentation conform in so far, since boost::thread doc states, that you
might only cancel threads which are in an interruption point or will enter
it. Asio or Boost::Threads simply ignore each other and nowhere in the docs
of asio is stated smth about boost::threads, but as it seems asio socket
when it waits for input is in such an interruption point (may be it uses
boost::threads internally) and therefore can be interrupted, but that's not
documented. I tested this with gcc compiler and it worked. May be this would
be a possible fix for asio developers to promise that synchronous sockets
are interruptable via boost::thread interruption.
Actually in my case it was a prototype, and it stayed so and I probably
would never rely on that in the production code, but wanted to show that
there might be a quick fix for this issue.
Best Regards,
Ovanes
On Wed, Mar 4, 2009 at 10:23 AM, Stephan Menzel <stephan.menzel_at_gmx.eu>wrote:
> Is the subject Jehova enough for you? ;-)
>
> Great.
>
> Well, I haven't raised the subject so far but I'd certainly like to do so
> now. For years now I am not only a user but also an admirer of boost asio.
> Something that has always puzzled me however is, why a timeout functionality
> which is something very common and essential for sync IO just doesn't seem
> to be there.
>
> I think there are cases where syncronous IO is a better way to go and no
> async approach is sensible. In my case this is a collection of static
> functions that do UDP communication and therefore have to be sync because I
> just want them to be able to return and throw exceptions and be able to be
> called from anyone at any time.
>
> As always when I stumble across the asio/timeout problem I start googling
> around. When people raise the topic here they are usually pointed to an
> answer Chris Kohlhoff gave to someone asking that:
>
> http://lists.boost.org/Archives/boost/2007/04/120339.php
>
> ... which is good for tcp and works alright even though in my opinion it
> leaves the question why it has to be so compilicated to do something so
> basic. IMHO sync IO is all but pointless without a timeout.
>
> Anyway, I started to turn this into a UDP version and ended up with
> something very similar:
>
> inline void set_result(boost::optional<boost::system::error_code>* a,
> boost::system::error_code b) {
> a->reset(b);
> };
>
> template <typename MutableBufferSequence>
> void udp_read_with_timeout(boost::asio::ip::udp::socket& sock, int tmo,
> boost::asio::ip::udp::endpoint &endpoint, const MutableBufferSequence&
> buffers) {
>
> boost::optional<boost::system::error_code> timer_result;
> boost::asio::deadline_timer timer(sock.io_service());
> timer.expires_from_now(boost::posix_time::seconds(tmo));
> timer.async_wait(boost::bind(set_result, &timer_result, _1));
>
> boost::optional<boost::system::error_code> read_result;
> sock.async_receive_from(buffers, endpoint, boost::bind(set_result,
> &read_result, _1));
>
> sock.io_service().reset();
> while (sock.io_service().run_one()) {
> if (read_result)
> timer.cancel();
> else if (timer_result)
> sock.cancel();
> }
>
> if (*read_result)
> throw boost::system::system_error(*read_result);
> };
>
>
> So now I started to go ahead with that but I had to notice two things.
> First, the performance impact is massive to a point that forces me to
> reconsider. Second, when I use that in a multithreaded environment the whole
> thing seems to block in some threads randomly. I have made test program
> where I have multiple threads using that method, just sending an UDP request
> to a server and waiting for an answer using this function. In one thread
> everything is slow but continously running. In more than one thread it
> blocks for up to 5 or 6 seconds every few (10-20) runs for no visible
> reason. In my scenario all those threads share a socket protected by a mutex
> so if one of them blocks all will be halted.
>
> So I come to think this is not a good way to handle the problem. Does
> anyone have some thoughts on that? May this be a bug in asio (1.38) or
> perhaps in my function? Or is there a better way to do sync UDP IO with a
> timeout functionality?
>
> Cheers...
>
> Stephan
>
>
>
> _______________________________________________
> 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