217 *
218 * fd1 < 0 => close(fd2)
219 * fd1 >= 0 => dup2(fd1, fd2)
220 *
221 * Returns -1 with errno set if operation fails.
222 */
223 static int closefd(int fd1, int fd2) {
224 int rv, orig_errno;
225 fdEntry_t *fdEntry = getFdEntry(fd2);
226 if (fdEntry == NULL) {
227 errno = EBADF;
228 return -1;
229 }
230
231 /*
232 * Lock the fd to hold-off additional I/O on this fd.
233 */
234 pthread_mutex_lock(&(fdEntry->lock));
235
236 {
237 /*
238 * And close/dup the file descriptor
239 * (restart if interrupted by signal)
240 */
241 do {
242 if (fd1 < 0) {
243 rv = close(fd2);
244 } else {
245 rv = dup2(fd1, fd2);
246 }
247 } while (rv == -1 && errno == EINTR);
248
249 /*
250 * Send a wakeup signal to all threads blocked on this
251 * file descriptor.
252 */
253 threadEntry_t *curr = fdEntry->threads;
254 while (curr != NULL) {
255 curr->intr = 1;
256 pthread_kill( curr->thr, sigWakeup );
257 curr = curr->next;
258 }
259 }
260
261 /*
262 * Unlock without destroying errno
263 */
264 orig_errno = errno;
265 pthread_mutex_unlock(&(fdEntry->lock));
266 errno = orig_errno;
267
268 return rv;
269 }
270
271 /*
272 * Wrapper for dup2 - same semantics as dup2 system call except
273 * that any threads blocked in an I/O system call on fd2 will be
274 * preempted and return -1/EBADF;
275 */
276 int NET_Dup2(int fd, int fd2) {
277 if (fd < 0) {
278 errno = EBADF;
296 * Macro to perform a blocking IO operation. Restarts
297 * automatically if interrupted by signal (other than
298 * our wakeup signal)
299 */
300 #define BLOCKING_IO_RETURN_INT(FD, FUNC) { \
301 int ret; \
302 threadEntry_t self; \
303 fdEntry_t *fdEntry = getFdEntry(FD); \
304 if (fdEntry == NULL) { \
305 errno = EBADF; \
306 return -1; \
307 } \
308 do { \
309 startOp(fdEntry, &self); \
310 ret = FUNC; \
311 endOp(fdEntry, &self); \
312 } while (ret == -1 && errno == EINTR); \
313 return ret; \
314 }
315
316 int NET_Read(int s, void* buf, size_t len) {
317 BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
318 }
319
320 int NET_ReadV(int s, const struct iovec * vector, int count) {
321 BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
322 }
323
324 int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
325 struct sockaddr *from, int *fromlen) {
326 socklen_t socklen = *fromlen;
327 BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, &socklen) );
328 *fromlen = socklen;
329 }
330
331 int NET_Send(int s, void *msg, int len, unsigned int flags) {
332 BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) );
333 }
334
335 int NET_WriteV(int s, const struct iovec * vector, int count) {
407
408 /*
409 * If interrupted then adjust timeout. If timeout
410 * has expired return 0 (indicating timeout expired).
411 */
412 if (rv < 0 && errno == EINTR) {
413 if (timeout > 0) {
414 gettimeofday(&t, NULL);
415 newtime = t.tv_sec * 1000 + t.tv_usec / 1000;
416 timeout -= newtime - prevtime;
417 if (timeout <= 0) {
418 return 0;
419 }
420 prevtime = newtime;
421 }
422 } else {
423 return rv;
424 }
425
426 }
427 }
|
217 *
218 * fd1 < 0 => close(fd2)
219 * fd1 >= 0 => dup2(fd1, fd2)
220 *
221 * Returns -1 with errno set if operation fails.
222 */
223 static int closefd(int fd1, int fd2) {
224 int rv, orig_errno;
225 fdEntry_t *fdEntry = getFdEntry(fd2);
226 if (fdEntry == NULL) {
227 errno = EBADF;
228 return -1;
229 }
230
231 /*
232 * Lock the fd to hold-off additional I/O on this fd.
233 */
234 pthread_mutex_lock(&(fdEntry->lock));
235
236 {
237 /* On fast machines we see that we enter dup2 before the
238 * accepting thread had a chance to get and process the signal.
239 * So in case we woke a thread up, give it some time to cope.
240 * Also see https://bugs.openjdk.java.net/browse/JDK-8006395 */
241 int num_woken = 0;
242
243 /*
244 * Send a wakeup signal to all threads blocked on this
245 * file descriptor.
246 */
247 threadEntry_t *curr = fdEntry->threads;
248 while (curr != NULL) {
249 curr->intr = 1;
250 pthread_kill( curr->thr, sigWakeup );
251 num_woken ++;
252 curr = curr->next;
253 }
254
255 if (num_woken > 0) {
256 usleep(num_woken * 50);
257 }
258
259 /*
260 * And close/dup the file descriptor
261 * (restart if interrupted by signal)
262 */
263 do {
264 if (fd1 < 0) {
265 rv = close(fd2);
266 } else {
267 rv = dup2(fd1, fd2);
268 }
269 } while (rv == -1 && errno == EINTR);
270 }
271
272 /*
273 * Unlock without destroying errno
274 */
275 orig_errno = errno;
276 pthread_mutex_unlock(&(fdEntry->lock));
277 errno = orig_errno;
278
279 return rv;
280 }
281
282 /*
283 * Wrapper for dup2 - same semantics as dup2 system call except
284 * that any threads blocked in an I/O system call on fd2 will be
285 * preempted and return -1/EBADF;
286 */
287 int NET_Dup2(int fd, int fd2) {
288 if (fd < 0) {
289 errno = EBADF;
307 * Macro to perform a blocking IO operation. Restarts
308 * automatically if interrupted by signal (other than
309 * our wakeup signal)
310 */
311 #define BLOCKING_IO_RETURN_INT(FD, FUNC) { \
312 int ret; \
313 threadEntry_t self; \
314 fdEntry_t *fdEntry = getFdEntry(FD); \
315 if (fdEntry == NULL) { \
316 errno = EBADF; \
317 return -1; \
318 } \
319 do { \
320 startOp(fdEntry, &self); \
321 ret = FUNC; \
322 endOp(fdEntry, &self); \
323 } while (ret == -1 && errno == EINTR); \
324 return ret; \
325 }
326
327 int IO_Fcntl(int s, int cmd, void *arg) {
328 BLOCKING_IO_RETURN_INT( s, fcntl(s, cmd, arg) );
329 }
330
331 int IO_Write(int s, void* buf, size_t len) {
332 BLOCKING_IO_RETURN_INT( s, write(s, buf, len) );
333 }
334
335 int IO_Read(int s, void* buf, size_t len) {
336 BLOCKING_IO_RETURN_INT( s, read(s, buf, len) );
337 }
338
339 int NET_Read(int s, void* buf, size_t len) {
340 BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
341 }
342
343 int NET_ReadV(int s, const struct iovec * vector, int count) {
344 BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
345 }
346
347 int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
348 struct sockaddr *from, int *fromlen) {
349 socklen_t socklen = *fromlen;
350 BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, &socklen) );
351 *fromlen = socklen;
352 }
353
354 int NET_Send(int s, void *msg, int len, unsigned int flags) {
355 BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) );
356 }
357
358 int NET_WriteV(int s, const struct iovec * vector, int count) {
430
431 /*
432 * If interrupted then adjust timeout. If timeout
433 * has expired return 0 (indicating timeout expired).
434 */
435 if (rv < 0 && errno == EINTR) {
436 if (timeout > 0) {
437 gettimeofday(&t, NULL);
438 newtime = t.tv_sec * 1000 + t.tv_usec / 1000;
439 timeout -= newtime - prevtime;
440 if (timeout <= 0) {
441 return 0;
442 }
443 prevtime = newtime;
444 }
445 } else {
446 return rv;
447 }
448
449 }
450 }
451
452 /* hard coded values in java code do not match system header values */
453 #define JAVA_POLLIN 0x0001
454 #define JAVA_POLLOUT 0x0004
455 #define JAVA_POLLERR 0x0008
456 #define JAVA_POLLHUP 0x0010
457 #define JAVA_POLLNVAL 0x0020
458 #define JAVA_POLLREMOVE 0x0800 /* not used yet in Java but ment to deregister fd */
459
460 /* declared in src/solaris/native/java/net/net_util_md.h for AIX only */
461 int javaToNativeEvents(int javaEvents) {
462 int nativeEvents = 0;
463 if (javaEvents & JAVA_POLLIN) nativeEvents |= POLLIN;
464 if (javaEvents & JAVA_POLLOUT) nativeEvents |= POLLOUT;
465 if (javaEvents & JAVA_POLLERR) nativeEvents |= POLLERR;
466 if (javaEvents & JAVA_POLLHUP) nativeEvents |= POLLHUP;
467 if (javaEvents & JAVA_POLLNVAL) nativeEvents |= POLLNVAL;
468 if (javaEvents & JAVA_POLLREMOVE) {
469 /* For the time being we don't support JAVA_POLLREMOVE on AIX. Just check. */
470 fprintf(stderr, "POLLREMOVE not supported on AIX");
471 }
472 return nativeEvents;
473 }
474
475 /* declared in src/solaris/native/java/net/net_util_md.h for AIX only */
476 int nativeToJavaEvents(int nativeEvents) {
477 int javaEvents = 0;
478 if (nativeEvents & POLLIN) javaEvents |= JAVA_POLLIN;
479 if (nativeEvents & POLLOUT) javaEvents |= JAVA_POLLOUT;
480 if (nativeEvents & POLLERR) javaEvents |= JAVA_POLLERR;
481 if (nativeEvents & POLLHUP) javaEvents |= JAVA_POLLHUP;
482 if (nativeEvents & POLLNVAL) javaEvents |= JAVA_POLLNVAL;
483 return javaEvents;
484 }
|