1 /* 2 * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.nio.ch; 27 28 import java.io.IOException; 29 30 /** 31 * Manipulates a native array of pollfd structs on Solaris: 32 * 33 * typedef struct pollfd { 34 * int fd; 35 * short events; 36 * short revents; 37 * } pollfd_t; 38 * 39 * @author Mike McCloskey 40 * @since 1.4 41 */ 42 43 class DevPollArrayWrapper { 44 45 // special event to remove a file descriptor from the driver 46 static final short POLLREMOVE = 0x0800; 47 48 // struct pollfd constants 49 static final short SIZE_POLLFD = 8; 50 static final short FD_OFFSET = 0; 51 static final short EVENT_OFFSET = 4; 52 static final short REVENT_OFFSET = 6; 53 54 // maximum number of pollfd structure to poll or update at a time 55 // dpwrite/ioctl(DP_POLL) allows up to file descriptor limit minus 1 56 static final int NUM_POLLFDS = Math.min(IOUtil.fdLimit()-1, 1024); 57 58 // The pollfd array for results from devpoll driver 59 private final AllocatedNativeObject pollArray; 60 61 // Base address of the native pollArray 62 private final long pollArrayAddress; 63 64 // The fd of the devpoll driver 65 private int wfd; 66 67 DevPollArrayWrapper() throws IOException { 68 this.wfd = init(); 69 70 int allocationSize = NUM_POLLFDS * SIZE_POLLFD; 71 this.pollArray = new AllocatedNativeObject(allocationSize, true); 72 this.pollArrayAddress = pollArray.address(); 73 } 74 75 void close() throws IOException { 76 FileDispatcherImpl.closeIntFD(wfd); 77 pollArray.free(); 78 } 79 80 void register(int fd, int ops) throws IOException { 81 register(wfd, fd, ops); 82 } 83 84 void registerMultiple(int numfds) throws IOException { 85 registerMultiple(wfd, pollArrayAddress, numfds); 86 } 87 88 int poll(long timeout) throws IOException { 89 return poll0(pollArrayAddress, NUM_POLLFDS, timeout, wfd); 90 } 91 92 int getDescriptor(int i) { 93 int offset = SIZE_POLLFD * i + FD_OFFSET; 94 return pollArray.getInt(offset); 95 } 96 97 short getEventOps(int i) { 98 int offset = SIZE_POLLFD * i + EVENT_OFFSET; 99 return pollArray.getShort(offset); 100 } 101 102 short getReventOps(int i) { 103 int offset = SIZE_POLLFD * i + REVENT_OFFSET; 104 return pollArray.getShort(offset); 105 } 106 107 /** 108 * Updates the pollfd structure at the given index 109 */ 110 void putPollFD(int index, int fd, short event) { 111 int structIndex = SIZE_POLLFD * index; 112 pollArray.putInt(structIndex + FD_OFFSET, fd); 113 pollArray.putShort(structIndex + EVENT_OFFSET, event); 114 pollArray.putShort(structIndex + REVENT_OFFSET, (short)0); 115 } 116 117 private native int init() throws IOException; 118 private native void register(int wfd, int fd, int mask) throws IOException; 119 private native void registerMultiple(int wfd, long address, int len) 120 throws IOException; 121 private native int poll0(long pollAddress, int numfds, long timeout, int wfd) 122 throws IOException; 123 124 static { 125 IOUtil.load(); 126 } 127 }