This is the mail archive of the java-patches@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]

[PATCH]: DatagramChannel + Misc. Channel Fixes


Hi Michael,

I updated my NetTest with a DatagramChannel test and then
fixed libgcj to make this test work. Here is the patch,
which is against the trunk but will assuredly apply cleanly
to 3.4 also.

(I will eventually put these into Mauve if someone doesn't
do it before I do.)

I needed yet another "in channel operation" indicator, but
this time I needed to put it into DatagramChannelImpl instead
of the datagram socket implementation, which I wasn't allowed
to touch. I thought of a nice way of getting rid of some of
this ugliness, but it's too far-reaching for 3.4 and I'd
prefer getting this checked in first (if you like it) before
proceeding with the refactoring.

I've attached my updated NetTest as well as the output of
this test under both Sun's JRE (1.4.1-rc-b19) and gcj. As
I mentioned in a previous post, I believe that the
"--> Interrupted!" lines in the gcj output which are
not present in the Sun output are correct and that Sun's
implementation is incorrect.

Enjoy.

-- Mohan
http://www.thisiscool.com/
http://www.animalsong.org/

ChangeLog
2004-02-01  Mohan Embar  <gnustuff@thisiscool.com>

	* gnu/java/nio/DatagramChannelImpl.java
	(inChannelOperation): New field.
	(isInChannelOperation): New accessor.
	(setInChannelOperation): New modifier.
	(receive): Use capacity() - position() of destination
	buffer instead of remaining(). Set and reset our "in
	channel operation indicator" before and after delegating
	the receive to our datagram socket. Removed testing code.
	Update destination buffer's current position if it is
	backed by a byte array (hasArray() is true).
	(send): Set and reset our "in channel operation indicator"
	before and after delegating the send to our datagram socket.
	Removed testing code. Update source buffer's current position
	if it is backed by a byte array (hasArray() is true).
	* gnu/java/nio/SocketChannelImpl.java (read(ByteBuffer)):
	Use capacity() - position() of destination buffer instead
	of remaining().
	* java/net/DatagramSocket.java (receive): Don't throw an
	IllegalBlockingModeException if we have a non-blocking
	channel which initiated this operation.
	(send): Likewise.

Index: gnu/java/nio/DatagramChannelImpl.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/nio/DatagramChannelImpl.java,v
retrieving revision 1.8
diff -c -3 -p -r1.8 DatagramChannelImpl.java
*** gnu/java/nio/DatagramChannelImpl.java	7 Jan 2004 16:51:49 -0000	1.8
--- gnu/java/nio/DatagramChannelImpl.java	1 Feb 2004 17:01:29 -0000
*************** public final class DatagramChannelImpl e
*** 57,62 ****
--- 57,89 ----
  {
    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 <code>IllegalBlockingModeException</code> if
+    * we are in non-blocking mode, <i>except</i> 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
    {
*************** public final class DatagramChannelImpl e
*** 178,184 ****
      try
        {
          DatagramPacket packet;
!         int len = dst.remaining();
          
          if (dst.hasArray())
            {
--- 205,211 ----
      try
        {
          DatagramPacket packet;
!         int len = dst.capacity() - dst.position();
          
          if (dst.hasArray())
            {
*************** public final class DatagramChannelImpl e
*** 196,218 ****
          try
            {
              begin();
              socket.receive (packet);
              completed = true;
            }
          finally
            {
              end (completed);
            }
  
          if (!dst.hasArray())
            {
              dst.put (packet.getData(), packet.getOffset(), packet.getLength());
            }
! 
!         // FIMXE: remove this testing code.
!         for (int i = 0; i < packet.getLength(); i++)
            {
!             System.out.println ("Byte " + i + " has value " + packet.getData() [packet.getOffset() + i]);
            }
  
          return packet.getSocketAddress();
--- 223,245 ----
          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());
            }
!         else
            {
!             dst.position (dst.position() + packet.getLength());
            }
  
          return packet.getSocketAddress();
*************** public final class DatagramChannelImpl e
*** 246,258 ****
  
      DatagramPacket packet = new DatagramPacket (buffer, offset, len, target);
  
!     // FIMXE: remove this testing code.
!     for (int i = 0; i < packet.getLength(); i++)
        {
!         System.out.println ("Byte " + i + " has value " + packet.getData() [packet.getOffset() + i]);
        }
  
-     socket.send (packet);
      return len;
    }
  }
--- 273,297 ----
  
      DatagramPacket packet = new DatagramPacket (buffer, offset, len, target);
  
!     boolean completed = false;
!     try
!       {
!         begin();
!         setInChannelOperation(true);
!         socket.send(packet);
!         completed = true;
!       }
!     finally
!       {
!         end (completed);
!         setInChannelOperation(false);
!       }
!       
!     if (src.hasArray())
        {
! 	src.position (src.position() + len);
        }
  
      return len;
    }
  }
Index: gnu/java/nio/SocketChannelImpl.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/nio/SocketChannelImpl.java,v
retrieving revision 1.16
diff -c -3 -p -r1.16 SocketChannelImpl.java
*** gnu/java/nio/SocketChannelImpl.java	30 Jan 2004 13:43:18 -0000	1.16
--- gnu/java/nio/SocketChannelImpl.java	1 Feb 2004 17:01:30 -0000
*************** public final class SocketChannelImpl ext
*** 226,232 ****
      int offset = 0;
      InputStream input = socket.getInputStream();
      int available = input.available();
!     int len = dst.remaining();
  	
      if (available == 0)
        return 0;
--- 226,232 ----
      int offset = 0;
      InputStream input = socket.getInputStream();
      int available = input.available();
!     int len = dst.capacity() - dst.position();
  	
      if (available == 0)
        return 0;
Index: java/net/DatagramSocket.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/net/DatagramSocket.java,v
retrieving revision 1.35
diff -c -3 -p -r1.35 DatagramSocket.java
*** java/net/DatagramSocket.java	9 Dec 2003 15:39:23 -0000	1.35
--- java/net/DatagramSocket.java	1 Feb 2004 17:01:32 -0000
*************** exception statement from your version. *
*** 39,44 ****
--- 39,45 ----
  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;
*************** public class DatagramSocket
*** 565,571 ****
          ("Socket connected to a multicast address my not receive");
  
      if (getChannel() != null
!         && !getChannel().isBlocking ())
        throw new IllegalBlockingModeException ();
  
      getImpl().receive(p);
--- 566,573 ----
          ("Socket connected to a multicast address my not receive");
  
      if (getChannel() != null
!         && !getChannel().isBlocking ()
!         && !((DatagramChannelImpl) getChannel()).isInChannelOperation())
        throw new IllegalBlockingModeException ();
  
      getImpl().receive(p);
*************** public class DatagramSocket
*** 618,624 ****
      // use getTimeToLive for TTL val.
  
      if (getChannel() != null
!         && !getChannel().isBlocking ())
        throw new IllegalBlockingModeException ();
  
      getImpl().send(p);
--- 620,627 ----
      // use getTimeToLive for TTL val.
  
      if (getChannel() != null
!         && !getChannel().isBlocking ()
!         && !((DatagramChannelImpl) getChannel()).isInChannelOperation())
        throw new IllegalBlockingModeException ();
  
      getImpl().send(p);

Attachment: NetTest.tar.bz2
Description: application/bzip2


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