OSDN Git Service

* testsuite/thread/pthread1.cc: Enable on cygwin.
[pf3gnuchains/gcc-fork.git] / libjava / posix.cc
1 // posix.cc -- Helper functions for POSIX-flavored OSs.
2
3 /* Copyright (C) 2000, 2001  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 #include <config.h>
12
13 #include "posix.h"
14
15 #include <errno.h>
16
17 #include <jvm.h>
18 #include <java/lang/Thread.h>
19 #include <java/io/InterruptedIOException.h>
20
21 #if defined (ECOS)
22 extern "C" unsigned long long _clock (void);
23 #endif
24
25 // gettimeofday implementation.
26 void
27 _Jv_gettimeofday (struct timeval *tv)
28 {
29 #if defined (HAVE_GETTIMEOFDAY)
30   gettimeofday (tv, NULL);
31 #elif defined (HAVE_TIME)
32   tv->tv_sec = time (NULL);
33   tv->tv_usec = 0;
34 #elif defined (HAVE_FTIME)
35   struct timeb t;
36   ftime (&t);
37   tv->tv_sec = t.time;
38   tv->tv_usec = t.millitm * 1000;
39 #elif defined (ECOS)
40   // FIXME.
41   tv->tv_sec = _clock () / 1000;
42   tv->tv_usec = 0;
43 #else
44   // In the absence of any function, time remains forever fixed.
45   tv->tv_sec = 23;
46   tv->tv_usec = 0;
47 #endif
48 }
49
50 // A wrapper for select() which ignores EINTR.
51 int
52 _Jv_select (int n, fd_set *readfds, fd_set  *writefds,
53             fd_set *exceptfds, struct timeval *timeout)
54 {
55 #ifdef HAVE_SELECT
56   // If we have a timeout, compute the absolute ending time.
57   struct timeval end, delay;
58   if (timeout)
59     {
60       _Jv_gettimeofday (&end);
61       end.tv_usec += timeout->tv_usec;
62       if (end.tv_usec >= 1000000)
63         {
64           ++end.tv_sec;
65           end.tv_usec -= 1000000;
66         }
67       end.tv_sec += timeout->tv_sec;
68       delay = *timeout;
69     }
70   else
71     {
72       // Placate compiler.
73       delay.tv_sec = delay.tv_usec = 0;
74     }
75
76   while (1)
77     {
78       int r = select (n, readfds, writefds, exceptfds,
79                       timeout ? &delay : NULL);
80       if (r != -1 || errno != EINTR)
81         return r;
82
83       // Here we know we got EINTR.
84       if (java::lang::Thread::interrupted ())
85         throw new java::io::InterruptedIOException (JvNewStringLatin1 ("select interrupted"));
86
87       struct timeval after;
88       if (timeout)
89         {
90           _Jv_gettimeofday (&after);
91           // Now compute new timeout argument.
92           delay.tv_usec = end.tv_usec - after.tv_usec;
93           delay.tv_sec = end.tv_sec - after.tv_sec;
94           if (delay.tv_usec < 0)
95             {
96               --delay.tv_sec;
97               delay.tv_usec += 1000000;
98             }
99           if (delay.tv_sec < 0)
100             {
101               // We assume that the user wants a valid select() call
102               // more than precise timing.  So if we get a series of
103               // EINTR we just keep trying with delay 0 until we get a
104               // valid result.
105               delay.tv_sec = 0;
106             }
107         }
108     }
109 #else /* HAVE_SELECT */
110   return 0;
111 #endif
112 }