This is the mail archive of the java@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Problem with SelectionKey OP_CONNECT


Doing some further testing I found problems with my attempted patch. In the connect() method I needed to set connectionPending to true. I also could not figure out why this was set to true during the SocketTimeOutException so I removed it.

-------------------------
// Do non-blocking connect.
try
{
socket.connect (remote, NIOConstants.DEFAULT_TIMEOUT);
connectionPending = true; return true;
}
catch (SocketTimeoutException e)
{
return false;
}
-------------------------


Accepting sockets off a server socket channel results in the socket being considered not connected and it will throw a "NotYetConnectedException" in any attempts to read/write to the socket. I fixed this by making the "connected" variable in SocketChannelImpl protected and putting this in the ServerSocketChannelImpl accept method:

--------------------------
((SocketChannelImpl)socket.getChannel()).connected = socket.isConnected();
--------------------------


before returning the socket channel. Looks hackish but worked.

Hello,

I have noticed a difference between gcj and Sun's implementation of NIO socket channels. GCJ is not setting the readyOps when a socket is connectable. I wrote an example program to illustrate the problem:
-------------------------
import java.net.InetSocketAddress;
import java.nio.channels.*;
import java.util.Iterator;


public class TestConnect
{
   public TestConnect()
   {
       try
       {
           Selector selector = Selector.open();
           SocketChannel channel = SocketChannel.open();
           channel.configureBlocking(false);
           channel.connect(new InetSocketAddress("gcc.gnu.org", 80));
           channel.register(selector, SelectionKey.OP_CONNECT);
                     while (true)
           {
               selector.select();
               Iterator it = selector.selectedKeys().iterator();
                     while (it.hasNext())
               {
                   SelectionKey selKey = (SelectionKey)it.next();
                                     if (selKey.isConnectable())
                   {
                       System.out.println("Connection ready");
                       System.exit(0);
                   }
               }
           }
       }
       catch (Exception ex)
       {
           ex.printStackTrace();
       }
   }
     public static void main(String[] args)
   {
       new TestConnect();
   }
}
-------------------------

Looking at the SelectorImpl.select(long) method I noticed that there is a section commented out that would add OP_CONNECT if the channel is not connected and the fd is in the write array. I put it back in like such:

-------------------------
if (key.getNativeFD() == write[i])
{
if (key.channel() instanceof SocketChannel)
{
if ( ((SocketChannel)key.channel()).isConnected ())
{
ops = ops | SelectionKey.OP_WRITE;
}
else
{
ops = ops | SelectionKey.OP_CONNECT;
}
}
else
{
ops = ops | SelectionKey.OP_WRITE;
}
}
-------------------------


The problem, I believe, is that the SocketChannelImpl.isConnected() returns true on a non-blocking socket even if the finishConnect() has not been called. So I modified it:

68d67
<   private boolean connected;
150,152d148
<            <             connected = true;
<            195d190
<         connected = true;
203d197
<         connected = true;
212,214c206
<     if (connected)
<         connected = socket.isConnected();
<     return connected;
---
>     return socket.isConnected();

What I basically did was add a "connected" boolean flag. connect() for blocking sockets can set this flag to true. Non-blocking sockets can only toggle this by calling finishConnect(). isConnected() will only check the status of the actual socket if the flag is true, otherwise always return false.

Does anyone see a problem with this? It seems to work fine.

I am using Mohan's gcc (GCC) 3.5.0 20040629 (experimental) on Windows XP SP1



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]