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

Patch: select -vs- EINTR


Currently we assume that all signal handlers are installed using
SA_RESTART.  However, select() doesn't restart -- it will error out
with EINTR.  This patch changes libgcj to recognize this and then
restart the select.  I'm checking this in.

2000-08-02  Tom Tromey  <tromey@cygnus.com>

	* Makefile.in: Rebuilt.
	* Makefile.am (libgcj_la_SOURCES): Added posix.cc.
	* java/net/natPlainSocketImpl.cc: Include posix.h.
	(accept): Use _Jv_select.
	* java/net/natPlainDatagramSocketImpl.cc: Include posix.h.
	(receive): Use _Jv_select.
	* java/io/natFileDescriptorPosix.cc: Include posix.h.
	(available): Use _Jv_select.
	* java/lang/natSystem.cc: Include posix.h.
	(currentTimeMillis): Use _Jv_gettimeofday.
	* include/posix.h: New file.
	* posix.cc: New file.

Tom

Index: Makefile.am
===================================================================
RCS file: /cvs/java/libgcj/libjava/Makefile.am,v
retrieving revision 1.74
diff -u -r1.74 Makefile.am
--- Makefile.am	2000/08/02 19:56:52	1.74
+++ Makefile.am	2000/08/02 21:46:32
@@ -118,7 +118,7 @@
 ## Extract the libffi object file names.
 libffi_files = `$(AR) t ../libffi/.libs/libffi.a 2>/dev/null | sed 's/\.o/\.lo/g' | sed 's/^/..\/libffi\//g'`
 
-libgcj_la_SOURCES = prims.cc jni.cc exception.cc \
+libgcj_la_SOURCES = prims.cc posix.cc jni.cc exception.cc \
 	resolve.cc defineclass.cc interpret.cc name-finder.cc
 EXTRA_libgcj_la_SOURCES = boehm.cc nogc.cc posix-threads.cc no-threads.cc \
 	$(c_source_files) $(java_source_files) $(built_java_source_files)
Index: posix.cc
===================================================================
RCS file: posix.cc
diff -N posix.cc
--- /dev/null	Tue May  5 13:32:27 1998
+++ posix.cc	Wed Aug  2 14:46:35 2000
@@ -0,0 +1,104 @@
+// posix.cc -- Helper functions for POSIX-flavored OSs.
+
+/* Copyright (C) 2000  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include "posix.h"
+
+#include <errno.h>
+
+#if defined (ECOS)
+extern "C" unsigned long long _clock (void);
+#endif
+
+// gettimeofday implementation.
+void
+_Jv_gettimeofday (struct timeval *tv)
+{
+#if defined (HAVE_GETTIMEOFDAY)
+  gettimeofday (tv, NULL);
+#elif defined (HAVE_TIME)
+  tv->tv_sec = time (NULL);
+  tv->tv_usec = 0;
+#elif defined (HAVE_FTIME)
+  struct timeb t;
+  ftime (&t);
+  tv->tv_sec = t.time;
+  tv->tv_usec = t.millitm * 1000;
+#elif defined (ECOS)
+  // FIXME.
+  tv->tv_sec = _clock () / 1000;
+  tv->tv_usec = 0;
+#else
+  // In the absence of any function, time remains forever fixed.
+  tv->tv_sec = 23;
+  tv->tv_usec = 0;
+#endif
+}
+
+// A wrapper for select() which ignores EINTR.
+int
+_Jv_select (int n, fd_set *readfds, fd_set  *writefds,
+	    fd_set *exceptfds, struct timeval *timeout)
+{
+#ifdef HAVE_SELECT
+  // If we have a timeout, compute the absolute ending time.
+  struct timeval end, delay;
+  if (timeout)
+    {
+      _Jv_gettimeofday (&end);
+      end.tv_usec += timeout->tv_usec;
+      if (end.tv_usec >= 1000000)
+	{
+	  ++end.tv_sec;
+	  end.tv_usec -= 1000000;
+	}
+      end.tv_sec += timeout->tv_sec;
+      delay = *timeout;
+    }
+  else
+    {
+      // Placate compiler.
+      delay.tv_sec = delay.tv_usec = 0;
+    }
+
+  while (1)
+    {
+      int r = select (n, readfds, writefds, exceptfds,
+		      timeout ? &delay : NULL);
+      if (r != -1 || errno != EINTR)
+	return r;
+
+      struct timeval after;
+      if (timeout)
+	{
+	  _Jv_gettimeofday (&after);
+	  // Now compute new timeout argument.
+	  delay.tv_usec = end.tv_usec - after.tv_usec;
+	  delay.tv_sec = end.tv_sec - after.tv_sec;
+	  if (delay.tv_usec < 0)
+	    {
+	      --delay.tv_sec;
+	      delay.tv_usec += 1000000;
+	    }
+	  if (delay.tv_sec < 0)
+	    {
+	      // We assume that the user wants a valid select() call
+	      // more than precise timing.  So if we get a series of
+	      // EINTR we just keep trying with delay 0 until we get a
+	      // valid result.
+	      delay.tv_sec = 0;
+	    }
+	}
+    }
+#else /* HAVE_SELECT */
+  return 0;
+#endif
+}
Index: include/posix.h
===================================================================
RCS file: posix.h
diff -N posix.h
--- /dev/null	Tue May  5 13:32:27 1998
+++ posix.h	Wed Aug  2 14:46:35 2000
@@ -0,0 +1,27 @@
+// posix.h -- Helper functions for POSIX-flavored OSs.
+
+/* Copyright (C) 2000  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <time.h>
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+extern int _Jv_select (int n, fd_set *, fd_set *, fd_set *, struct timeval *);
+extern void _Jv_gettimeofday (struct timeval *);
Index: java/io/natFileDescriptorPosix.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/io/natFileDescriptorPosix.cc,v
retrieving revision 1.9
diff -u -r1.9 natFileDescriptorPosix.cc
--- natFileDescriptorPosix.cc	2000/06/28 12:24:10	1.9
+++ natFileDescriptorPosix.cc	2000/08/02 21:46:35
@@ -10,16 +10,11 @@
 
 #include <config.h>
 
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+#include "posix.h"
+
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/param.h>
 #include <fcntl.h>
@@ -309,7 +304,7 @@
       struct timeval tv;
       tv.tv_sec = 0;
       tv.tv_usec = 0;
-      r = ::select (fd + 1, &rd, NULL, NULL, &tv);
+      r = _Jv_select (fd + 1, &rd, NULL, NULL, &tv);
       if (r == -1)
 	goto posix_error;
       num = r == 0 ? 0 : 1;
Index: java/lang/natSystem.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/natSystem.cc,v
retrieving revision 1.21
diff -u -r1.21 natSystem.cc
--- natSystem.cc	2000/04/21 20:38:42	1.21
+++ natSystem.cc	2000/08/02 21:46:35
@@ -11,16 +11,9 @@
 #include <config.h>
 
 #include <string.h>
-#include <time.h>
 #include <stdlib.h>
 
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
+#include "posix.h"
 
 #ifdef HAVE_PWD_H
 #include <pwd.h>
@@ -48,10 +41,6 @@
 
 
 
-#if defined (ECOS)
-extern "C" unsigned long long _clock (void);
-#endif
-
 void
 java::lang::System::setErr (java::io::PrintStream *newErr)
 {
@@ -152,24 +141,9 @@
 {
   jlong r;
 
-#if defined (HAVE_GETTIMEOFDAY)
   struct timeval tv;
-  gettimeofday (&tv, NULL);
-  r = (jlong) tv.tv_sec * 1000 + tv.tv_usec / 1000;
-#elif defined (HAVE_TIME)
-  r = time (NULL) * 1000;
-#elif defined (HAVE_FTIME)
-  struct timeb t;
-  ftime (&t);
-  r = t.time * 1000 + t.millitm;
-#elif defined (ECOS)
-  r = _clock();
-#else
-  // In the absence of any function, time remains forever fixed.
-  r = 23;
-#endif
-
-  return r;
+  _Jv_gettimeofday (&tv);
+  return (jlong) tv.tv_sec * 1000 + tv.tv_usec / 1000;
 }
 
 jint
Index: java/net/natPlainDatagramSocketImpl.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/net/natPlainDatagramSocketImpl.cc,v
retrieving revision 1.19
diff -u -r1.19 natPlainDatagramSocketImpl.cc
--- natPlainDatagramSocketImpl.cc	2000/03/15 22:03:19	1.19
+++ natPlainDatagramSocketImpl.cc	2000/08/02 21:46:35
@@ -17,16 +17,10 @@
 #define ENOPROTOOPT 109
 #endif
 #else /* USE_WINSOCK */
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
+#include "posix.h"
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
 #endif
-#include <sys/time.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
@@ -314,7 +308,7 @@
       tv.tv_sec = timeout / 1000;
       tv.tv_usec = (timeout % 1000) * 1000;
       int retval;
-      if ((retval = select (fnum + 1, &rset, NULL, NULL, &tv)) < 0)
+      if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0)
 	goto error;
       else if (retval == 0)
 	JvThrow (new java::io::InterruptedIOException ());
Index: java/net/natPlainSocketImpl.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/net/natPlainSocketImpl.cc,v
retrieving revision 1.18
diff -u -r1.18 natPlainSocketImpl.cc
--- natPlainSocketImpl.cc	2000/03/15 22:03:19	1.18
+++ natPlainSocketImpl.cc	2000/08/02 21:46:35
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999  Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -19,12 +19,8 @@
 #define ENOPROTOOPT 109
 #endif
 #else /* USE_WINSOCK */
-#include <sys/types.h>
+#include "posix.h"
 #include <sys/socket.h>
-#include <sys/time.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <errno.h>
@@ -249,7 +245,7 @@
       tv.tv_sec = timeout / 1000;
       tv.tv_usec = (timeout % 1000) * 1000;
       int retval;
-      if ((retval = select (fnum + 1, &rset, NULL, NULL, &tv)) < 0)
+      if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0)
 	goto error;
       else if (retval == 0)
 	JvThrow (new java::io::InterruptedIOException (

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