* gnu/java/net/PlainSocketImpl.java
authorMohan Embar <gnustuff@thisiscool.com>
Fri, 30 Jan 2004 13:43:21 +0000 (13:43 +0000)
committerMohan Embar <membar@gcc.gnu.org>
Fri, 30 Jan 2004 13:43:21 +0000 (13:43 +0000)
(inChannelOperation): New field.
(isInChannelOperation): New accessor.
(setInChannelOperation): New modifier.
* gnu/java/nio/ServerSocketChannelImpl.java
(accept): Set and reset our server socket's PlainSocketImpl's
"in channel operation" indicator before and after delegating
the accept to our server socket.
* gnu/java/nio/SocketChannelImpl.java
(connect): Set and reset our socket's PlainSocketImpl's "in channel
operation" indicator before and after delegating the operation to
our socket.
(read): Likewise.
(write): Likewise.
* java/net/ServerSocket.java (implAccept): Don't throw an
IllegalBlockingModeException if we have a non-blocking
channel which initiated this accept operation.
* java/net/Socket.java (connect): Don't throw an
IllegalBlockingModeException if we have a non-blocking
channel which initiated this connect operation.
* java/nio/channels/spi/AbstractSelectableChannel.java
(configureBlocking): Only call implConfigureBlocking() if
the desired blocking mode is different from our current one.

From-SVN: r76956

libjava/ChangeLog
libjava/gnu/java/net/PlainSocketImpl.java
libjava/gnu/java/nio/ServerSocketChannelImpl.java
libjava/gnu/java/nio/SocketChannelImpl.java
libjava/java/net/ServerSocket.java
libjava/java/net/Socket.java
libjava/java/nio/channels/spi/AbstractSelectableChannel.java

index aa6242fca3621c65d5c24a46f396a94ace230e19..1376be8ecac77b8f96bdd61f55cd066b6e303cfc 100644 (file)
@@ -1,3 +1,29 @@
+2004-01-30  Mohan Embar  <gnustuff@thisiscool.com>
+
+       * gnu/java/net/PlainSocketImpl.java 
+       (inChannelOperation): New field.
+       (isInChannelOperation): New accessor.
+       (setInChannelOperation): New modifier.
+       * gnu/java/nio/ServerSocketChannelImpl.java
+       (accept): Set and reset our server socket's PlainSocketImpl's
+       "in channel operation" indicator before and after delegating
+       the accept to our server socket.
+       * gnu/java/nio/SocketChannelImpl.java
+       (connect): Set and reset our socket's PlainSocketImpl's "in channel
+       operation" indicator before and after delegating the operation to
+       our socket.
+       (read): Likewise.
+       (write): Likewise.
+       * java/net/ServerSocket.java (implAccept): Don't throw an
+       IllegalBlockingModeException if we have a non-blocking
+       channel which initiated this accept operation.
+       * java/net/Socket.java (connect): Don't throw an
+       IllegalBlockingModeException if we have a non-blocking
+       channel which initiated this connect operation.
+       * java/nio/channels/spi/AbstractSelectableChannel.java
+       (configureBlocking): Only call implConfigureBlocking() if
+       the desired blocking mode is different from our current one.
+
 2004-01-29  Mohan Embar  <gnustuff@thisiscool.com>
 
        * java/io/BufferedReader.java (sbuf): New field.
index 80139115cfe09e547224d3956b740fe5882c6682..5680fb30cbe6507064bbe1747dd295d911ba7759 100644 (file)
@@ -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.
@@ -119,6 +119,33 @@ public final class PlainSocketImpl extends SocketImpl
    */
   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 <code>IllegalBlockingModeException</code> if the
+   * associated channel is in non-blocking mode, <i>except</i>
+   * 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 fd975d20a7ad540bfa07b41989395cf134cc83f8..76e1ce3242f59eac81371dbbb3b5d826b984dae2 100644 (file)
@@ -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.
 
@@ -69,7 +69,7 @@ public final class ServerSocketChannelImpl extends ServerSocketChannel
   {
     return serverSocket.getPlainSocketImpl().getNativeFD();
   }
+  
   public void finalizer()
   {
     if (connected)
@@ -107,6 +107,11 @@ public final class ServerSocketChannelImpl extends ServerSocketChannel
     
     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 @@ public final class ServerSocketChannelImpl extends ServerSocketChannel
       }
     finally
       {
+        serverSocket.getPlainSocketImpl().setInChannelOperation(false);
         end (completed);
       }
   }
index efb5fec481b7dd88b79b2338e4763501373f594d..4df40b481a6df0a9915ab2d7a2dc1811030de422 100644 (file)
@@ -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,23 +136,35 @@ public final class SocketChannelImpl extends SocketChannel
     if (((InetSocketAddress) remote).isUnresolved())
       throw new UnresolvedAddressException();
     
-    if (isBlocking())
-      {
-        // Do blocking connect.
-        socket.connect (remote);
-        return true;
-      }
-
-    // Do non-blocking connect.
     try
       {
-        socket.connect (remote, NIOConstants.DEFAULT_TIMEOUT);
-        return true;
+        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.
+            socket.connect (remote);
+            return true;
+          }
+
+        // Do non-blocking connect.
+        try
+          {
+            socket.connect (remote, NIOConstants.DEFAULT_TIMEOUT);
+            return true;
+          }
+        catch (SocketTimeoutException e)
+          {
+            connectionPending = true;
+            return false;
+          }
       }
-    catch (SocketTimeoutException e)
+    finally
       {
-        connectionPending = true;
-        return false;
+        socket.getPlainSocketImpl().setInChannelOperation(false);
       }
   }
     
@@ -238,12 +250,14 @@ public final class SocketChannelImpl extends SocketChannel
     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 @@ public final class SocketChannelImpl extends SocketChannel
       }
 
     OutputStream output = socket.getOutputStream();
-    output.write (data, offset, len);
+    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 9a2d82d9c7615ec60732569988a70a0210576831..a53ebf674d1372a8cd003f58fb870d0c5153d78c 100644 (file)
@@ -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 @@ public class ServerSocket
     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 9322e929ec38b6755990f805e5371282244ddda4..f9cbb7e6cb344f629fb6479c51864052d19cb775 100644 (file)
@@ -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 @@ public class Socket
     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 17d6a2eaea1f90361d2d8130111434b8a4468e45..76c6c2b899f866f76dc375f0220abf4e2e6143f0 100644 (file)
@@ -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 @@ public abstract class AbstractSelectableChannel extends SelectableChannel
   {
     synchronized (blockingLock())
       {
-        implConfigureBlocking(blocking);
-        this.blocking = blocking;
+        if (this.blocking != blocking)
+          {
+            implConfigureBlocking(blocking);
+            this.blocking = blocking;
+          }
       }
     
     return this;