Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/sun/nio/ch/DevPollArrayWrapper.c
32288 views
/*1* Copyright (c) 2001, 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"29#include "sun_nio_ch_DevPollArrayWrapper.h"30#include <sys/poll.h>31#include <unistd.h>32#include <sys/time.h>3334#ifdef __cplusplus35extern "C" {36#endif3738typedef uint32_t caddr32_t;3940/* /dev/poll ioctl */41#define DPIOC (0xD0 << 8)42#define DP_POLL (DPIOC | 1) /* poll on fds in cached in /dev/poll */43#define DP_ISPOLLED (DPIOC | 2) /* is this fd cached in /dev/poll */44#define DEVPOLLSIZE 1000 /* /dev/poll table size increment */45#define POLLREMOVE 0x0800 /* Removes fd from monitored set */4647/*48* /dev/poll DP_POLL ioctl format49*/50typedef struct dvpoll {51pollfd_t *dp_fds; /* pollfd array */52nfds_t dp_nfds; /* num of pollfd's in dp_fds[] */53int dp_timeout; /* time out in millisec */54} dvpoll_t;5556typedef struct dvpoll32 {57caddr32_t dp_fds; /* pollfd array */58uint32_t dp_nfds; /* num of pollfd's in dp_fds[] */59int32_t dp_timeout; /* time out in millisec */60} dvpoll32_t;6162#ifdef __cplusplus63}64#endif6566#define RESTARTABLE(_cmd, _result) do { \67do { \68_result = _cmd; \69} while((_result == -1) && (errno == EINTR)); \70} while(0)7172static int73idevpoll(jint wfd, int dpctl, struct dvpoll a)74{75jlong start, now;76int remaining = a.dp_timeout;77struct timeval t;78int diff;7980gettimeofday(&t, NULL);81start = t.tv_sec * 1000 + t.tv_usec / 1000;8283for (;;) {84/* poll(7d) ioctl does not return remaining count */85int res = ioctl(wfd, dpctl, &a);86if (res < 0 && errno == EINTR) {87if (remaining >= 0) {88gettimeofday(&t, NULL);89now = t.tv_sec * 1000 + t.tv_usec / 1000;90diff = now - start;91remaining -= diff;92if (diff < 0 || remaining <= 0) {93return 0;94}95start = now;96a.dp_timeout = remaining;97}98} else {99return res;100}101}102}103104JNIEXPORT jint JNICALL105Java_sun_nio_ch_DevPollArrayWrapper_init(JNIEnv *env, jobject this)106{107int wfd = open("/dev/poll", O_RDWR);108if (wfd < 0) {109JNU_ThrowIOExceptionWithLastError(env, "Error opening driver");110return -1;111}112return wfd;113}114115JNIEXPORT void JNICALL116Java_sun_nio_ch_DevPollArrayWrapper_register(JNIEnv *env, jobject this,117jint wfd, jint fd, jint mask)118{119struct pollfd a[1];120int n;121122a[0].fd = fd;123a[0].events = mask;124a[0].revents = 0;125126n = write(wfd, &a[0], sizeof(a));127if (n != sizeof(a)) {128if (n < 0) {129JNU_ThrowIOExceptionWithLastError(env, "Error writing pollfds");130} else {131JNU_ThrowIOException(env, "Unexpected number of bytes written");132}133}134}135136JNIEXPORT void JNICALL137Java_sun_nio_ch_DevPollArrayWrapper_registerMultiple(JNIEnv *env, jobject this,138jint wfd, jlong address,139jint len)140{141unsigned char *pollBytes = (unsigned char *)jlong_to_ptr(address);142unsigned char *pollEnd = pollBytes + sizeof(struct pollfd) * len;143while (pollBytes < pollEnd) {144int bytesWritten = write(wfd, pollBytes, (int)(pollEnd - pollBytes));145if (bytesWritten < 0) {146JNU_ThrowIOExceptionWithLastError(env, "Error writing pollfds");147return;148}149pollBytes += bytesWritten;150}151}152153JNIEXPORT jint JNICALL154Java_sun_nio_ch_DevPollArrayWrapper_poll0(JNIEnv *env, jobject this,155jlong address, jint numfds,156jlong timeout, jint wfd)157{158struct dvpoll a;159void *pfd = (void *) jlong_to_ptr(address);160int result = 0;161162a.dp_fds = pfd;163a.dp_nfds = numfds;164a.dp_timeout = (int)timeout;165166if (timeout <= 0) { /* Indefinite or no wait */167RESTARTABLE (ioctl(wfd, DP_POLL, &a), result);168} else { /* Bounded wait; bounded restarts */169result = idevpoll(wfd, DP_POLL, a);170}171172if (result < 0) {173JNU_ThrowIOExceptionWithLastError(env, "Error reading driver");174return -1;175}176return result;177}178179JNIEXPORT void JNICALL180Java_sun_nio_ch_DevPollArrayWrapper_interrupt(JNIEnv *env, jclass this, jint fd)181{182int fakebuf[1];183fakebuf[0] = 1;184if (write(fd, fakebuf, 1) < 0) {185JNU_ThrowIOExceptionWithLastError(env,186"Write to interrupt fd failed");187}188}189190191