Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/sun/nio/ch/EPollArrayWrapper.c
32288 views
/*1* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include "jni.h"26#include "jni_util.h"27#include "jvm.h"28#include "jlong.h"2930#include "sun_nio_ch_EPollArrayWrapper.h"3132#include <unistd.h>33#include <sys/time.h>34#include <sys/epoll.h>3536#define RESTARTABLE(_cmd, _result) do { \37do { \38_result = _cmd; \39} while((_result == -1) && (errno == EINTR)); \40} while(0)414243static int44iepoll(int epfd, struct epoll_event *events, int numfds, jlong timeout)45{46jlong start, now;47int remaining = timeout;48struct timeval t;49int diff;5051gettimeofday(&t, NULL);52start = t.tv_sec * 1000 + t.tv_usec / 1000;5354for (;;) {55int res = epoll_wait(epfd, events, numfds, remaining);56if (res < 0 && errno == EINTR) {57if (remaining >= 0) {58gettimeofday(&t, NULL);59now = t.tv_sec * 1000 + t.tv_usec / 1000;60diff = now - start;61remaining -= diff;62if (diff < 0 || remaining <= 0) {63return 0;64}65start = now;66}67} else {68return res;69}70}71}7273JNIEXPORT void JNICALL74Java_sun_nio_ch_EPollArrayWrapper_init(JNIEnv *env, jclass this)75{76}7778JNIEXPORT jint JNICALL79Java_sun_nio_ch_EPollArrayWrapper_epollCreate(JNIEnv *env, jobject this)80{81/*82* epoll_create expects a size as a hint to the kernel about how to83* dimension internal structures. We can't predict the size in advance.84*/85int epfd = epoll_create(256);86if (epfd < 0) {87JNU_ThrowIOExceptionWithLastError(env, "epoll_create failed");88}89return epfd;90}9192JNIEXPORT jint JNICALL93Java_sun_nio_ch_EPollArrayWrapper_sizeofEPollEvent(JNIEnv* env, jclass this)94{95return sizeof(struct epoll_event);96}9798JNIEXPORT jint JNICALL99Java_sun_nio_ch_EPollArrayWrapper_offsetofData(JNIEnv* env, jclass this)100{101return offsetof(struct epoll_event, data);102}103104JNIEXPORT void JNICALL105Java_sun_nio_ch_EPollArrayWrapper_epollCtl(JNIEnv *env, jobject this, jint epfd,106jint opcode, jint fd, jint events)107{108struct epoll_event event;109int res;110111event.events = events;112event.data.fd = fd;113114RESTARTABLE(epoll_ctl(epfd, (int)opcode, (int)fd, &event), res);115116/*117* A channel may be registered with several Selectors. When each Selector118* is polled a EPOLL_CTL_DEL op will be inserted into its pending update119* list to remove the file descriptor from epoll. The "last" Selector will120* close the file descriptor which automatically unregisters it from each121* epoll descriptor. To avoid costly synchronization between Selectors we122* allow pending updates to be processed, ignoring errors. The errors are123* harmless as the last update for the file descriptor is guaranteed to124* be EPOLL_CTL_DEL.125*/126if (res < 0 && errno != EBADF && errno != ENOENT && errno != EPERM) {127JNU_ThrowIOExceptionWithLastError(env, "epoll_ctl failed");128}129}130131JNIEXPORT jint JNICALL132Java_sun_nio_ch_EPollArrayWrapper_epollWait(JNIEnv *env, jobject this,133jlong address, jint numfds,134jlong timeout, jint epfd)135{136struct epoll_event *events = jlong_to_ptr(address);137int res;138139if (timeout <= 0) { /* Indefinite or no wait */140RESTARTABLE(epoll_wait(epfd, events, numfds, timeout), res);141} else { /* Bounded wait; bounded restarts */142res = iepoll(epfd, events, numfds, timeout);143}144145if (res < 0) {146JNU_ThrowIOExceptionWithLastError(env, "epoll_wait failed");147}148return res;149}150151JNIEXPORT void JNICALL152Java_sun_nio_ch_EPollArrayWrapper_interrupt(JNIEnv *env, jobject this, jint fd)153{154int fakebuf[1];155fakebuf[0] = 1;156if (write(fd, fakebuf, 1) < 0) {157JNU_ThrowIOExceptionWithLastError(env,"write to interrupt fd failed");158}159}160161162