Boost logo

Boost Users :

Subject: Re: [Boost-users] boost::asio blocking socket read with timeout with multiple threads
From: Stian Zeljko Vrba (vrba_at_[hidden])
Date: 2018-03-23 10:56:07


You should probably not use boost to handle signals. The page about signalfd (https://linux.die.net/man/2/signalfd) has this remark: Normally, the set of signals to be received via the file descriptor should be blocked using sigprocmask(2), to prevent the signals being handled according to their default dispositions. So I would expect that boost does exactly this and therefore the synchronous read doesn't get interrupted. (If boost didn't block the signal, the behavior would be "default disposition", i.e., termination as you have observed).

So try the following: install a signal handler for SIGALRM (or any other) and do NOT wait for it using boost. Have the handler just return and see whether blocking recv got interrupted. However... it's not that simple. Signals and threads don't play nicely together: a signal will be delivered to an arbitrary thread that didn't block it.

So you should have a variable holding the thread id of the thread running your io_context::run, and from within the signal handler:

  1.
Check whether the thread executing the handler is different from the thread running io_context::run
  2.
If so, use pthread_kill to re-deliver the signal to the correct thread.
  3.
Otherwise, do nothing.

Signal handlers are global to the process, so w/o the check for the thread you can end up in an endless loop.

Yeah, it's a mess compared to Windows CancelSynchronousIO

________________________________
From: Boost-users <boost-users-bounces_at_[hidden]> on behalf of Thomas Quarendon via Boost-users <boost-users_at_[hidden]>
Sent: Friday, March 23, 2018 11:23:59 AM
To: boost-users_at_[hidden]
Cc: tom_at_[hidden]
Subject: Re: [Boost-users] boost::asio blocking socket read with timeout with multiple threads

> Of course the correct way to "cancel" a sync call in linux is to raise a
> signal, which should cause the socket's read to return with EINTR.

Hmm. Can't see any evidence of it working in my test. I've made my deadline callback do a raise(SIGALRM). If I don't have a handler for that signal, then my process terminates, which I guess is fair enough. If I have a (boost asio) handler and essentially ignore the signal (just print "signal handled" from my signal handler), the signal is handled, but my read doesn't return. My recollection of the boost asio code for socket recv is that it doesn't simply perform a raw socket recv call, but rather it loops in case of error, with a "poll" call in there too.

So while that technique may work OK for a raw socket, it doesn't work with asio.
_______________________________________________
Boost-users mailing list
Boost-users_at_[hidden]
https://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