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: remove all traces of java.io.FileDescriptor from java.net


While testing our application with 3.1, I had trouble with sockets closing
prematurely, and traced it to the finalizer in FileDescriptor.  I don't
know if it's masking another bug, but the patch below solved my problem,
and is more portable anyway... we had determined some time ago that file
descriptors and sockets don't mix.

I have no good way to test the datagram code, since I never use it for my
application.  But normal sockets appear to be functioning normally with
this patch, and are finalized correctly.

Tested on i686-linux.  OK for 3.1 branch and mainline?

2002-03-24  Jeff Sturm  <jsturm@one-point.com>

	* java/net/DatagramSocketImpl.java
	(java.io.FileDescriptor): Don't import.
	(fd): Remove instance variable.
	(getFileDescriptor): Remove method.

	* java/net/PlainDatagramSocketImpl.java
	(close): Use native implementation.
	(finalize): New method.

	* java/net/PlainSocketImpl.java (finalize): New method.

	* java/net/SocketImpl.java (fd): Remove instance variable.
	(getFileDescriptor): Remove method.

	* java/net/natPlainDatagramSocketImpl.cc
	(java/io/FileDescriptor.h): Don't include.
	(close): Implement method here.
	(create): Don't assign fd.

	* java/net/natPlainSocketImpl.cc
	(java/io/FileDescriptor.h): Don't include.
	(create): Don't assign fd.
	(accept): Likewise.

Index: java/net/DatagramSocketImpl.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/net/DatagramSocketImpl.java,v
retrieving revision 1.8
diff -u -p -r1.8 DatagramSocketImpl.java
--- DatagramSocketImpl.java	2002/02/14 23:16:06	1.8
+++ DatagramSocketImpl.java	2002/03/25 02:39:16
@@ -39,7 +39,6 @@ exception statement from your version. *
 package java.net;
 
 import java.io.IOException;
-import java.io.FileDescriptor;
 
 /**
  * Written using on-line Java Platform 1.2 API Specification, as well
@@ -62,11 +61,6 @@ public abstract class DatagramSocketImpl
   protected int localPort;
 
   /**
-   * The FileDescriptor object for this object.
-   */
-  protected FileDescriptor fd;
-
-  /**
    * Default, no-argument constructor for subclasses to call.
    */
   public DatagramSocketImpl()
@@ -185,14 +179,6 @@ public abstract class DatagramSocketImpl
    * @exception IOException If an error occurs
    */
   protected abstract void leave(InetAddress inetaddr) throws IOException;
-
-  /**
-   * Returns the FileDescriptor for this socket
-   */
-  protected FileDescriptor getFileDescriptor()
-  {
-    return fd;
-  }
 
   /**
    * Returns the local port this socket is bound to
Index: java/net/PlainDatagramSocketImpl.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/net/PlainDatagramSocketImpl.java,v
retrieving revision 1.9
diff -u -p -r1.9 PlainDatagramSocketImpl.java
--- PlainDatagramSocketImpl.java	2000/12/08 10:28:32	1.9
+++ PlainDatagramSocketImpl.java	2002/03/25 02:39:16
@@ -67,28 +67,8 @@ class PlainDatagramSocketImpl extends Da
   public native Object getOption(int optID) throws SocketException;
   private native void mcastGrp(InetAddress inetaddr, boolean join)
 	throws IOException;
+  protected native void close();
 
-  protected void close()
-  {
-    // FIXME: The close method in each of the DatagramSocket* classes does
-    // not throw an IOException.  The issue is that FileDescriptor.close()
-    // in natFileDescriptorPosix.cc can throw one, so we have to catch
-    // it here.  It seems that FileDescriptor.close is properly throwing
-    // the IOException on errors since many of the java.io classes depend
-    // on that.  This probably requires a bit more research but for now,
-    // we'll catch the IOException here.
-    try
-      {
-        if (fd.valid())
-	  fd.close();
-      }
-    catch (IOException e)
-      {
-	System.err.println("PlainDatagramSocketImpl.close: Error closing - " +
-	  e.getMessage());
-      }
-  }
-
   // Deprecated in JDK 1.2.
   protected byte getTTL() throws IOException
   {
@@ -109,5 +89,12 @@ class PlainDatagramSocketImpl extends Da
   protected void leave(InetAddress inetaddr) throws IOException
   {
     mcastGrp(inetaddr, false);
+  }
+
+  protected void finalize() throws Throwable
+  {
+    if (fnum != -1)
+      close();
+    super.finalize();
   }
 }
Index: java/net/PlainSocketImpl.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/net/PlainSocketImpl.java,v
retrieving revision 1.9
diff -u -p -r1.9 PlainSocketImpl.java
--- PlainSocketImpl.java	2002/01/08 21:14:58	1.9
+++ PlainSocketImpl.java	2002/03/25 02:39:16
@@ -39,11 +39,6 @@ class PlainSocketImpl extends SocketImpl
    * This is used for reads and writes to/from the socket and
    * to close it.
    *
-   * {@link SocketImpl#fd} is created from this like so:
-   * <pre>
-   *   fd = new FileDescriptor (fnum);
-   * </pre>
-   *
    * When the socket is closed this is reset to -1.
    */
   int fnum = -1;
@@ -108,6 +103,19 @@ class PlainSocketImpl extends SocketImpl
   private native void write(byte[] buffer, int offset, int count)
     throws IOException;
 
+  protected void finalize() throws Throwable
+  {
+    if (fnum != -1)
+      try
+	{
+	  close();
+	}
+      catch (IOException ex)
+	{
+	  // ignore
+	}
+    super.finalize();
+  }
 
   /** @return the input stream attached to the socket.
    */
Index: java/net/SocketImpl.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/net/SocketImpl.java,v
retrieving revision 1.8
diff -u -p -r1.8 SocketImpl.java
--- SocketImpl.java	2002/02/14 23:16:06	1.8
+++ SocketImpl.java	2002/03/25 02:39:16
@@ -67,11 +67,6 @@ public abstract class SocketImpl impleme
   protected InetAddress address;
 
   /**
-   * A FileDescriptor object representing this socket connection.
-   */
-  protected FileDescriptor fd;
-
-  /**
    * The port number the socket is bound to locally
    */
   protected int localport;
@@ -192,13 +187,6 @@ public abstract class SocketImpl impleme
    * @exception IOException If an error occurs
    */
   protected abstract void close() throws IOException;
-
-  /**
-   * Returns the FileDescriptor objects for this socket.
-   *
-   * @return A FileDescriptor for this socket.
-   */
-  protected FileDescriptor getFileDescriptor() { return fd; }
 
   /**
    * Returns the remote address this socket is connected to
Index: java/net/natPlainDatagramSocketImpl.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/net/natPlainDatagramSocketImpl.cc,v
retrieving revision 1.33.2.1
diff -u -p -r1.33.2.1 natPlainDatagramSocketImpl.cc
--- natPlainDatagramSocketImpl.cc	2002/03/10 18:00:06	1.33.2.1
+++ natPlainDatagramSocketImpl.cc	2002/03/25 02:39:16
@@ -51,7 +51,6 @@ _Jv_bind (int fd, struct sockaddr *addr,
 
 #include <gcj/cni.h>
 #include <java/io/IOException.h>
-#include <java/io/FileDescriptor.h>
 #include <java/io/InterruptedIOException.h>
 #include <java/net/BindException.h>
 #include <java/net/SocketException.h>
@@ -91,6 +90,13 @@ java::net::PlainDatagramSocketImpl::peek
 }
 
 void
+java::net::PlainDatagramSocketImpl::close ()
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.close: unimplemented"));
+}
+
+void
 java::net::PlainDatagramSocketImpl::send (java::net::DatagramPacket *)
 {
   throw new java::io::IOException (
@@ -189,7 +195,6 @@ java::net::PlainDatagramSocketImpl::crea
   _Jv_platform_close_on_exec (sock);
 
   fnum = sock;
-  fd = new java::io::FileDescriptor (sock);
 }
 
 void
@@ -282,6 +287,18 @@ java::net::PlainDatagramSocketImpl::peek
  error:
   char* strerr = strerror (errno);
   throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+// Close(shutdown) the socket.
+void
+java::net::PlainDatagramSocketImpl::close ()
+{
+  // The method isn't declared to throw anything, so we disregard
+  // the return value.
+  ::close (fnum);
+
+  // Safe place to reset the file descriptor.
+  fnum = -1;
 }
 
 void
Index: java/net/natPlainSocketImpl.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/net/natPlainSocketImpl.cc,v
retrieving revision 1.30.2.6
diff -u -p -r1.30.2.6 natPlainSocketImpl.cc
--- natPlainSocketImpl.cc	2002/03/11 03:43:56	1.30.2.6
+++ natPlainSocketImpl.cc	2002/03/25 02:39:16
@@ -102,7 +102,6 @@ _Jv_accept (int fd, struct sockaddr *add
 #include <gcj/cni.h>
 #include <gcj/javaprims.h>
 #include <java/io/IOException.h>
-#include <java/io/FileDescriptor.h>
 #include <java/io/InterruptedIOException.h>
 #include <java/net/BindException.h>
 #include <java/net/ConnectException.h>
@@ -235,7 +234,6 @@ java::net::PlainSocketImpl::create (jboo
   _Jv_platform_close_on_exec (sock);
 
   fnum = sock;
-  fd = new java::io::FileDescriptor (sock);
 }
 
 void
@@ -402,7 +400,6 @@ java::net::PlainSocketImpl::accept (java
   s->localport = localport;
   s->address = new InetAddress (raddr, NULL);
   s->port = rport;
-  s->fd = new java::io::FileDescriptor (new_socket);
   return;
  error:
   char* strerr = strerror (errno);


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