This is the mail archive of the
java-patches@sources.redhat.com
mailing list for the Java project.
Patch: select -vs- EINTR
- To: Java Patch List <java-patches at sourceware dot cygnus dot com>
- Subject: Patch: select -vs- EINTR
- From: Tom Tromey <tromey at cygnus dot com>
- Date: 02 Aug 2000 16:05:02 -0600
- Reply-To: tromey at cygnus dot com
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 (