so_rcv_sx, deadlkres, SIGSTOP
Jilles Tjoelker
jilles at stack.nl
Sun Apr 4 20:40:58 UTC 2010
On Sun, Apr 04, 2010 at 09:12:33PM +0300, Kostik Belousov wrote:
> On Sun, Apr 04, 2010 at 07:51:40PM +0200, Jilles Tjoelker wrote:
> > The SX locks so_snd_sx and so_rcv_sx can be legitimately held for
> > arbitrary amounts of time, while waiting until a send or recv is
> > possible. Any other threads wanting to send/recv on the socket will
> > sleep interruptibly on the corresponding SX. If deadlkres is activated,
> > it may detect a deadlock even though there is no problem.
> > If a SIGSTOP or similar comes in while waiting until send/recv is
> > possible, the SX is held across the suspension and noone will be able to
> > send/recv on the socket until the process is resumed. On the other hand
> > a thread waiting for the SX can be suspended without harm. Adding PBDRY
> > to various sleeps may help but may also introduce other problems
> > (SIGSTOP disturbing the functioning of the process more, possibly with
> > stuff like SO_RCVTIMEO).
> Could you, please, elaborate on this (interaction between PBDRY and some
> socket timeout stuff) ?
A SIGSTOP will currently not affect a SO_RCVTIMEO timeout, just like it
does not affect a nanosleep(2).
Demonstration is analogous to my earlier example with /bin/sleep,
where ./socktimeout is the program below:
% /usr/bin/time ./socktimeout
^Z
% fg # such that the program can run again 10 seconds after starting
socktimeout: read: Resource temporarily unavailable
10.00 real 0.00 user 0.00 sys
%
PBDRY would cause an immediate Interrupted system call return.
I don't know how much SO_RCVTIMEO/SO_SNDTIMEO are used (a POSIX
application cannot rely on their support for any kind of socket), and it
is likely applications using it can already get EINTR from signal
handlers.
#include <sys/socket.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
int sock;
sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
if (sock == -1)
err(1, "socket");
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
&(const struct timeval){ 10, 0 }, sizeof(struct timeval)) == -1)
err(1, "setsockopt(SO_RCVTIMEO)");
errno = 0;
if (read(sock, (char[]){ 0 }, 1) != 1)
err(1, "read");
return 0;
}
--
Jilles Tjoelker
More information about the freebsd-arch
mailing list