On 08/23/12 05:54 PM, Mark Kettenis wrote:
From: Arvind Umrao<[email protected]>
Date: Thu, 23 Aug 2012 16:07:39 +0530

Code changes are integrated in Solaris and now I am trying to give back to 
community. If Socket is getting interrupted with signal EINTR, we should keep 
socket in progress state(TRANS_IN_PROGRESS) instead of trying again to 
connect(TRANS_TRY_CONNECT_AGAIN). When we close the socket connection on signal 
EINTR and retry, we will end up in same old state and stuck in loop. As per 
documentation if Connect() is interrupted by a signal that is caught, while 
blocked waiting to establish a connection, connect() shall fail and set 
connect() to [EINTR], but the connection request shall not be aborted, and the 
connection shall be established asynchronously. When the connection has been 
established asynchronously, select() and poll() shall indicate that the file 
descriptor for the socket is ready for writing.

Referhttp://www.madore.org/~david/computers/connect-intr.html
The problem with this change is that currently TRANS_IN_PROGRESS could
only happen for TRANS_NONBLOCKING sockets, whereas with this change it
suddenly can happen for normal blocking sockets as well.

For both blocking and non blocking, if connect()interrupted with Signal EINTR, it should return TRANS_IN_PROGRESS. When we close the socket connection on signal EINTR and retry, we end up in same old state and stuck in loop.

In Unix Network Programming, volume 1, section 5.9, W. Richard Stevens states:

What we are doing […] is restarting the interrupted system call ourself. This is fine for accept, along with the functions such as read, write, select and open. But there is one function that we cannot restart ourself: connect. If this function returns EINTR, we cannot call it again, as doing so will return an immediate error. When connect is interrupted by a caught signal and is not automatically restarted, we must call "Select" to wait for the connection to complete, as we describe in section 15.3.

Referencehttp://www.madore.org/~david/computers/connect-intr.html



Look for example at the code in libICE/src/connect.c:ConnectToPeer().
I wouldn't be surprised if the sleep(1) you see there was put in to
mitigate this problem.  Because of that sleep the connect() is likely
to succeed the next time around.  But with your change this turns into
a guaranteed failure!So I don't think you can make this change without making 
fixes to the
code that uses this functionality.  Is this code used outside of xorg?


I have tested in Solaris and also I can test it in Ubuntu. Even after sleep, connect() end up in same old state with signal EINTR. So sleep is not solving problem in both blocking and non blocking mode.With or without my code changes, connection will close when signal EINTR arrives, unless libICE/src/connect.c:ConnectToPeer() handles TRANS_IN_PROGRESS state. I have tested Connect() by setting blocking mode with _TransSetOption(trans_conn, TRANS_NONBLOCKING, 0);


In any case, if you make this change, you should also change the
comments that describe what the current EINTR behaviour.

Yes, I will do it. Request for approving patch I proposed for lib/libXfont, code changes are simple and obvious.

Thanks and Regards
-Arvind

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to