OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [native/] [jni/] [java-nio/] [gnu_java_nio_VMSelector.c] - Blame information for rev 774

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 774 jeremybenn
/* gnu_java_nio_VMSelector.c - Native methods for SelectorImpl class
2
   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
#include "config.h"
39
 
40
/* <sys/types.h> needs to be included on OSX before <sys/select.h> */
41
#if defined(HAVE_SYS_TYPES_H)
42
#include <sys/types.h>
43
#endif
44
#if defined(HAVE_SYS_SELECT_H)
45
#include <sys/select.h>
46
#endif
47
#include <sys/time.h>
48
 
49
#include <string.h>
50
 
51
#include <errno.h>
52
 
53
#include <jni.h>
54
#include <jcl.h>
55
 
56
#include "gnu_java_nio_VMSelector.h"
57
 
58
/* Amount of characters in the error message buffer for strerror_r. */
59
#define BUF_SIZE 250
60
 
61
void helper_put_filedescriptors (JNIEnv *, jintArray, fd_set *, int *);
62
 
63
void helper_get_filedescriptors (JNIEnv *, jintArray *, fd_set *);
64
 
65
void helper_reset (JNIEnv *, jintArray *);
66
 
67
int
68
helper_select (JNIEnv *, jclass, jmethodID,
69
               int, fd_set *, fd_set *, fd_set *, struct timeval *);
70
 
71
void
72
helper_put_filedescriptors (JNIEnv * env, jintArray fdArray, fd_set * fds,
73
                            int *max_fd)
74
{
75
  jint *tmpFDArray = (*env)->GetIntArrayElements (env, fdArray, 0);
76
  int size = (*env)->GetArrayLength (env, fdArray);
77
  int index, fd;
78
 
79
  for (index = 0; index < size; index++)
80
    {
81
      fd = tmpFDArray[index];
82
 
83
      if (fd > 0)
84
        {
85
          FD_SET (tmpFDArray[index], fds);
86
 
87
          if (tmpFDArray[index] > (*max_fd))
88
            (*max_fd) = tmpFDArray[index];
89
        }
90
    }
91
}
92
 
93
void
94
helper_get_filedescriptors (JNIEnv * env, jintArray * fdArray, fd_set * fds)
95
{
96
  jint *tmpFDArray = (*env)->GetIntArrayElements (env, fdArray, 0);
97
  int size = (*env)->GetArrayLength (env, fdArray);
98
  int index, fd;
99
 
100
  for (index = 0; index < size; index++)
101
    {
102
      fd = tmpFDArray[index];
103
      if (fd < 0 || !FD_ISSET (fd, fds))
104
        tmpFDArray[index] = 0;
105
    }
106
}
107
 
108
void
109
helper_reset (JNIEnv * env, jintArray * fdArray)
110
{
111
  jint *tmpFDArray = (*env)->GetIntArrayElements (env, fdArray, 0);
112
  int size = (*env)->GetArrayLength (env, fdArray);
113
  int index;
114
 
115
  for (index = 0; index < size; index++)
116
    tmpFDArray[index] = 0;
117
}
118
 
119
/* A wrapper for select() which ignores EINTR.
120
 * Taken from gclib's posix.cc
121
 */
122
int
123
helper_select (JNIEnv * env, jclass thread_class,
124
               jmethodID thread_interrupted, int n, fd_set * readfds,
125
               fd_set * writefds, fd_set * exceptfds, struct timeval *timeout)
126
{
127
#ifdef HAVE_SYS_SELECT_H
128
  /* If we have a timeout, compute the absolute ending time. */
129
  struct timeval end, delay, after;
130
  int r;
131
 
132
  if (timeout)
133
    {
134
      gettimeofday (&end, NULL);
135
 
136
      end.tv_usec += timeout->tv_usec;
137
 
138
      if (end.tv_usec >= 1000000)
139
        {
140
          ++end.tv_sec;
141
          end.tv_usec -= 1000000;
142
        }
143
 
144
      end.tv_sec += timeout->tv_sec;
145
      delay = *timeout;
146
    }
147
  else
148
    {
149
      /* Placate compiler. */
150
      delay.tv_sec = delay.tv_usec = 0;
151
    }
152
 
153
  while (1)
154
    {
155
      r = select (n, readfds, writefds, exceptfds, timeout ? &delay : NULL);
156
 
157
      if (r < 0 && errno != EINTR)
158
        return -errno;
159
      else if (r >= 0)
160
        return r;
161
 
162
      /* Here we know we got EINTR. */
163
      if ((*env)->
164
          CallStaticBooleanMethod (env, thread_class, thread_interrupted))
165
        {
166
          return -EINTR;
167
        }
168
 
169
      if (timeout)
170
        {
171
          gettimeofday (&after, NULL);
172
 
173
          /* Now compute new timeout argument. */
174
          delay.tv_usec = end.tv_usec - after.tv_usec;
175
          delay.tv_sec = end.tv_sec - after.tv_sec;
176
 
177
          if (delay.tv_usec < 0)
178
            {
179
              --delay.tv_sec;
180
              delay.tv_usec += 1000000;
181
            }
182
 
183
          if (delay.tv_sec < 0)
184
            {
185
              /* We assume that the user wants a valid select() call
186
               * more than precise timing.  So if we get a series of
187
               * EINTR we just keep trying with delay 0 until we get a
188
               * valid result.
189
               */
190
              delay.tv_sec = 0;
191
            }
192
        }
193
    }
194
#else /* HAVE_SYS_SELECT_H */
195
  return 0;
196
#endif
197
 
198
}
199
 
200
JNIEXPORT jint JNICALL
201
Java_gnu_java_nio_VMSelector_select (JNIEnv * env,
202
                                     jclass obj __attribute__ ((__unused__)),
203
                                     jintArray read,
204
                                     jintArray write,
205
                                     jintArray except, jlong timeout)
206
{
207
  jint result;
208
  jclass thread_class = (*env)->FindClass (env, "java/lang/Thread");
209
  jmethodID thread_current_thread =
210
    (*env)->GetStaticMethodID (env, thread_class, "currentThread",
211
                               "()Ljava/lang/Thread;");
212
  jmethodID thread_interrupt =
213
    (*env)->GetMethodID (env, thread_class, "interrupt", "()V");
214
  jmethodID thread_interrupted =
215
    (*env)->GetStaticMethodID (env, thread_class, "interrupted", "()Z");
216
  jobject current_thread;
217
  int max_fd = 0;
218
  fd_set read_fds;
219
  fd_set write_fds;
220
  fd_set except_fds;
221
  struct timeval real_time_data;
222
  struct timeval *time_data = NULL;
223
  char *message;
224
 
225
  /* If a legal timeout value isn't given, use NULL.
226
   * This means an infinite timeout. The specification
227
   * also says that a zero timeout should be treated
228
   * as infinite. Otherwise (if the timeout value is legal),
229
   * fill our timeval struct and use it for the select.
230
   */
231
  if (timeout > 0)
232
    {
233
      real_time_data.tv_sec = timeout / 1000;
234
      real_time_data.tv_usec = (timeout % 1000) * 1000;
235
      time_data = &real_time_data;
236
    }
237
 
238
  /* Reset all fd_set structures */
239
  FD_ZERO (&read_fds);
240
  FD_ZERO (&write_fds);
241
  FD_ZERO (&except_fds);
242
 
243
  /* Fill the fd_set data structures for the _Jv_select() call. */
244
  helper_put_filedescriptors (env, read, &read_fds, &max_fd);
245
  helper_put_filedescriptors (env, write, &write_fds, &max_fd);
246
  helper_put_filedescriptors (env, except, &except_fds, &max_fd);
247
 
248
  /* Actually do the select */
249
  result =
250
    helper_select (env, thread_class, thread_interrupted, max_fd + 1,
251
                   &read_fds, &write_fds, &except_fds, time_data);
252
 
253
  if (result == -EINTR)
254
    {
255
      /* The behavior of JRE 1.4.1 is that no exception is thrown
256
       * when the thread is interrupted, but the thread's interrupt
257
       * status is set. Clear all of our select sets and return 0,
258
       * indicating that nothing was selected.
259
       */
260
      current_thread =
261
        (*env)->CallStaticObjectMethod (env, thread_class,
262
                                        thread_current_thread);
263
      (*env)->CallVoidMethod (env, current_thread, thread_interrupt);
264
 
265
      helper_reset (env, read);
266
      helper_reset (env, write);
267
      helper_reset (env, except);
268
 
269
      return 0;
270
    }
271
 
272
  if (result < 0)
273
    {
274
#if defined(HAVE_STRERROR_R)
275
      char message_buf[BUF_SIZE+1];
276
      int errorcode = -result;
277
 
278
      if (strerror_r (errorcode, message_buf, BUF_SIZE))
279
        {
280
          /* This would mean that message_buf was to small
281
           * to hold the error message.
282
           */
283
          JCL_ThrowException (env, "java/lang/InternalError",
284
                              "Not enough space in message buffer.");
285
          return 0;
286
        }
287
 
288
      message = message_buf;
289
#else
290
      message = strerror(errno);
291
#endif
292
 
293
      JCL_ThrowException (env, "java/io/IOException", message);
294
      return 0;
295
    }
296
 
297
  /* Set the file descriptors according to the values returned from select(). */
298
  helper_get_filedescriptors (env, read, &read_fds);
299
  helper_get_filedescriptors (env, write, &write_fds);
300
  helper_get_filedescriptors (env, except, &except_fds);
301
 
302
  return result;
303
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.