tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: A possible bug with non-blocking sockets and SIGIO



Hi all,

On Sun, 6 Mar 2011 22:48:27 -0500 (EST), der Mouse <mouse%Rodents-Montreal.ORG@localhost> wrote:

onc.c does indeed have a race condition; given the interface design of
SIGIO, there is an unavoidable race between setting up SIGIO on a new
connection and data arriving.  Real servers using SIGIO need to take
care to check, after setting up SIGIO, for any data that may have
arrived before SIGIO was set up.

Sure. Actually, GNU Smalltalk sockets are made in this way. The implementation relies on SIGIO and carefully checks the conditions you've mentioned with poll(2). Here is a bit more details: http://dmitrymatveev.co.uk/blog?id=3

While onc.c does not do this, using
the given test method, this does not matter, because the delay
introduced by having a human initiate the test connection allows the
server plenty of time to establish SIGIO before the data arrives.

Yes, I have decided to not to complicate the example because of it.

I'm not sure whether O_ASYNC is supposed to be inherited from the
accepting socket to the accepted socket.  If it is, the relevant
process group setting needs to be copied as well; if not, the flags
copied need to have, at least, O_ASYNC deleted.  Adding additional
logging, I find that 1.4T does not copy O_ASYNC from the parent socket
to the child, so I think the correct change is probably to return to
the historical behaviour.  This is why I think Dmitry's change is not
the best: it, loosely put, copies O_ASYNC from socket to socket as well as from file descriptor to file descriptor, and I think it shouldn't be
copied.

As far as I know, the general rule to receive SIGIOs is to
1. Set O_ASYNC on a descriptor;
2. Specify a PID or GID there.
So I think it would be correct behavior for a process to set O_ASYNC and F_SETOWN for an accepted socket explicitly, i.e. the process should not count on the accepted socket's origins and flags inheritance. In this case my patch does not break the semantics.

I have modified onc.c a bit - now it does not set owner PID for an accepted socket. In the logs I see that a server's PID matches the value obtained by F_GETOWN for this socket, i.e. the relevant process group setting was copied, isn't it?

But I agree, the second variant (without copying) looks like more reliable, obvious and strict solution.

Dmitry



Home | Main Index | Thread Index | Old Index