Index: gnu/java/net/PlainSocketImpl.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/net/PlainSocketImpl.java,v retrieving revision 1.5 diff -u -b -B -r1.5 PlainSocketImpl.java --- gnu/java/net/PlainSocketImpl.java 20 Oct 2003 14:10:07 -0000 1.5 +++ gnu/java/net/PlainSocketImpl.java 6 Feb 2004 09:11:54 -0000 @@ -1,5 +1,5 @@ /* PlainSocketImpl.java -- Default socket implementation - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -96,6 +96,33 @@ */ private OutputStream out; + /** + * Indicates whether a channel initiated whatever operation + * is being invoked on this socket. + */ + private boolean inChannelOperation; + + /** + * Indicates whether we should ignore whether any associated + * channel is set to non-blocking mode. Certain operations + * throw an IllegalBlockingModeException if the + * associated channel is in non-blocking mode, except + * if the operation is invoked by the channel itself. + */ + public final boolean isInChannelOperation() + { + return inChannelOperation; + } + + /** + * Sets our indicator of whether an I/O operation is being + * initiated by a channel. + */ + public final void setInChannelOperation(boolean b) + { + inChannelOperation = b; + } + /** * Default do nothing constructor */ Index: gnu/java/nio/DatagramChannelImpl.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/nio/DatagramChannelImpl.java,v retrieving revision 1.10 diff -u -b -B -r1.10 DatagramChannelImpl.java --- gnu/java/nio/DatagramChannelImpl.java 8 Jan 2004 08:40:01 -0000 1.10 +++ gnu/java/nio/DatagramChannelImpl.java 6 Feb 2004 09:11:54 -0000 @@ -57,6 +57,33 @@ { private NIODatagramSocket socket; + /** + * Indicates whether this channel initiated whatever operation + * is being invoked on our datagram socket. + */ + private boolean inChannelOperation; + + /** + * Indicates whether our datagram socket should ignore whether + * we are set to non-blocking mode. Certain operations on our + * socket throw an IllegalBlockingModeException if + * we are in non-blocking mode, except if the operation + * is initiated by us. + */ + public final boolean isInChannelOperation() + { + return inChannelOperation; + } + + /** + * Sets our indicator of whether we are initiating an I/O operation + * on our socket. + */ + public final void setInChannelOperation(boolean b) + { + inChannelOperation = b; + } + protected DatagramChannelImpl (SelectorProvider provider) throws IOException { @@ -178,7 +205,7 @@ try { DatagramPacket packet; - int len = dst.remaining(); + int len = dst.capacity() - dst.position(); if (dst.hasArray()) { @@ -196,23 +223,23 @@ try { begin(); + setInChannelOperation(true); socket.receive (packet); completed = true; } finally { end (completed); + setInChannelOperation(false); } if (!dst.hasArray()) { dst.put (packet.getData(), packet.getOffset(), packet.getLength()); } - - // FIMXE: remove this testing code. - for (int i = 0; i < packet.getLength(); i++) + else { - System.out.println ("Byte " + i + " has value " + packet.getData() [packet.getOffset() + i]); + dst.position (dst.position() + packet.getLength()); } return packet.getSocketAddress(); @@ -246,13 +273,25 @@ DatagramPacket packet = new DatagramPacket (buffer, offset, len, target); - // FIMXE: remove this testing code. - for (int i = 0; i < packet.getLength(); i++) + boolean completed = false; + try + { + begin(); + setInChannelOperation(true); + socket.send(packet); + completed = true; + } + finally + { + end (completed); + setInChannelOperation(false); + } + + if (src.hasArray()) { - System.out.println ("Byte " + i + " has value " + packet.getData() [packet.getOffset() + i]); + src.position (src.position() + len); } - socket.send (packet); return len; } } Index: gnu/java/nio/NIOServerSocket.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/nio/NIOServerSocket.java,v retrieving revision 1.1 diff -u -b -B -r1.1 NIOServerSocket.java --- gnu/java/nio/NIOServerSocket.java 15 Oct 2003 12:51:32 -0000 1.1 +++ gnu/java/nio/NIOServerSocket.java 6 Feb 2004 09:11:54 -0000 @@ -1,5 +1,5 @@ /* NIOServerSocket.java -- - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -50,7 +50,6 @@ */ public final class NIOServerSocket extends ServerSocket { - private PlainSocketImpl impl; private ServerSocketChannelImpl channel; protected NIOServerSocket (ServerSocketChannelImpl channel) Index: gnu/java/nio/ServerSocketChannelImpl.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/nio/ServerSocketChannelImpl.java,v retrieving revision 1.10 diff -u -b -B -r1.10 ServerSocketChannelImpl.java --- gnu/java/nio/ServerSocketChannelImpl.java 8 Jan 2004 08:40:01 -0000 1.10 +++ gnu/java/nio/ServerSocketChannelImpl.java 6 Feb 2004 09:11:54 -0000 @@ -1,5 +1,5 @@ /* ServerSocketChannelImpl.java -- - Copyright (C) 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -107,6 +107,11 @@ try { + begin(); + serverSocket.getPlainSocketImpl().setInChannelOperation(true); + // indicate that a channel is initiating the accept operation + // so that the socket ignores the fact that we might be in + // non-blocking mode. NIOSocket socket = (NIOSocket) serverSocket.accept(); completed = true; return socket.getChannel(); @@ -117,6 +122,7 @@ } finally { + serverSocket.getPlainSocketImpl().setInChannelOperation(false); end (completed); } } Index: gnu/java/nio/SocketChannelImpl.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/nio/SocketChannelImpl.java,v retrieving revision 1.21 diff -u -b -B -r1.21 SocketChannelImpl.java --- gnu/java/nio/SocketChannelImpl.java 8 Jan 2004 08:40:01 -0000 1.21 +++ gnu/java/nio/SocketChannelImpl.java 6 Feb 2004 09:11:54 -0000 @@ -1,5 +1,5 @@ /* SocketChannelImpl.java -- - Copyright (C) 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -136,6 +136,13 @@ if (((InetSocketAddress) remote).isUnresolved()) throw new UnresolvedAddressException(); + try + { + socket.getPlainSocketImpl().setInChannelOperation(true); + // indicate that a channel is initiating the accept operation + // so that the socket ignores the fact that we might be in + // non-blocking mode. + if (isBlocking()) { // Do blocking connect. @@ -155,6 +162,11 @@ return false; } } + finally + { + socket.getPlainSocketImpl().setInChannelOperation(false); + } + } public boolean finishConnect () throws IOException @@ -162,7 +174,7 @@ if (!isOpen()) throw new ClosedChannelException(); - if (!connectionPending) + if (!isConnected() && !connectionPending) throw new NoConnectionPendingException(); if (isConnected()) @@ -214,7 +226,7 @@ int offset = 0; InputStream input = socket.getInputStream(); int available = input.available(); - int len = dst.remaining(); + int len = dst.capacity() - dst.position(); if (available == 0) return 0; @@ -238,12 +250,14 @@ try { begin(); + socket.getPlainSocketImpl().setInChannelOperation(true); readBytes = input.read (data, offset, len); completed = true; } finally { end (completed); + socket.getPlainSocketImpl().setInChannelOperation(false); } if (readBytes > 0) @@ -301,7 +315,20 @@ } OutputStream output = socket.getOutputStream(); + boolean completed = false; + + try + { + begin(); + socket.getPlainSocketImpl().setInChannelOperation(true); output.write (data, offset, len); + completed = true; + } + finally + { + end (completed); + socket.getPlainSocketImpl().setInChannelOperation(false); + } if (src.hasArray()) { Index: java/net/DatagramSocket.java =================================================================== RCS file: /cvsroot/classpath/classpath/java/net/DatagramSocket.java,v retrieving revision 1.37 diff -u -b -B -r1.37 DatagramSocket.java --- java/net/DatagramSocket.java 26 Dec 2003 22:21:56 -0000 1.37 +++ java/net/DatagramSocket.java 6 Feb 2004 09:11:54 -0000 @@ -39,6 +39,7 @@ package java.net; import gnu.java.net.PlainDatagramSocketImpl; +import gnu.java.nio.DatagramChannelImpl; import java.io.IOException; import java.nio.channels.DatagramChannel; import java.nio.channels.IllegalBlockingModeException; @@ -565,7 +566,8 @@ ("Socket connected to a multicast address my not receive"); if (getChannel() != null - && !getChannel().isBlocking ()) + && !getChannel().isBlocking () + && !((DatagramChannelImpl) getChannel()).isInChannelOperation()) throw new IllegalBlockingModeException (); getImpl().receive(p); @@ -618,7 +620,8 @@ // use getTimeToLive for TTL val. if (getChannel() != null - && !getChannel().isBlocking ()) + && !getChannel().isBlocking () + && !((DatagramChannelImpl) getChannel()).isInChannelOperation()) throw new IllegalBlockingModeException (); getImpl().send(p); Index: java/net/ServerSocket.java =================================================================== RCS file: /cvsroot/classpath/classpath/java/net/ServerSocket.java,v retrieving revision 1.32 diff -u -b -B -r1.32 ServerSocket.java --- java/net/ServerSocket.java 7 Jan 2004 16:38:02 -0000 1.32 +++ java/net/ServerSocket.java 6 Feb 2004 09:11:55 -0000 @@ -1,5 +1,6 @@ /* ServerSocket.java -- Class for implementing server side sockets - Copyright (C) 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -345,9 +346,14 @@ if (isClosed()) throw new SocketException("ServerSocket is closed"); + // The Sun spec says that if we have an associated channel and + // it is in non-blocking mode, we throw an IllegalBlockingModeException. + // However, in our implementation if the channel itself initiated this + // operation, then we must honor it regardless of its blocking mode. if (getChannel() != null - && !getChannel().isBlocking()) - throw new IllegalBlockingModeException(); + && !getChannel().isBlocking () + && !((PlainSocketImpl) getImpl()).isInChannelOperation()) + throw new IllegalBlockingModeException (); impl.accept(socket.getImpl()); } Index: java/net/Socket.java =================================================================== RCS file: /cvsroot/classpath/classpath/java/net/Socket.java,v retrieving revision 1.40 diff -u -b -B -r1.40 Socket.java --- java/net/Socket.java 26 Dec 2003 14:23:41 -0000 1.40 +++ java/net/Socket.java 6 Feb 2004 09:11:55 -0000 @@ -1,5 +1,6 @@ /* Socket.java -- Client socket implementation - Copyright (C) 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -420,8 +421,13 @@ if (! (endpoint instanceof InetSocketAddress)) throw new IllegalArgumentException("unsupported address type"); + // The Sun spec says that if we have an associated channel and + // it is in non-blocking mode, we throw an IllegalBlockingModeException. + // However, in our implementation if the channel itself initiated this + // operation, then we must honor it regardless of its blocking mode. if (getChannel() != null - && !getChannel().isBlocking ()) + && !getChannel().isBlocking () + && !((PlainSocketImpl) getImpl()).isInChannelOperation()) throw new IllegalBlockingModeException (); if (!isBound ()) Index: java/nio/channels/spi/AbstractSelectableChannel.java =================================================================== RCS file: /cvsroot/classpath/classpath/java/nio/channels/spi/AbstractSelectableChannel.java,v retrieving revision 1.11 diff -u -b -B -r1.11 AbstractSelectableChannel.java --- java/nio/channels/spi/AbstractSelectableChannel.java 8 Jan 2004 08:40:01 -0000 1.11 +++ java/nio/channels/spi/AbstractSelectableChannel.java 6 Feb 2004 09:11:55 -0000 @@ -1,5 +1,5 @@ /* AbstractSelectableChannel.java - Copyright (C) 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -80,8 +80,11 @@ { synchronized (blockingLock()) { + if (this.blocking != blocking) + { implConfigureBlocking(blocking); this.blocking = blocking; + } } return this;