1 /* 2 * Copyright (c) 2001, 2004, 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 sun.misc.*; 29 30 31 /** 32 * Manipulates a native array of pollfd structs on Solaris: 33 * 34 * typedef struct pollfd { 35 * int fd; 36 * short events; 37 * short revents; 38 * } pollfd_t; 39 * 40 * @author Mike McCloskey 41 * @since 1.4 42 */ 43 44 class PollArrayWrapper extends AbstractPollArrayWrapper { 45 46 static final short POLLCONN = POLLOUT; 47 48 // File descriptor to write for interrupt 49 int interruptFD; 50 PollArrayWrapper(int newSize)51 PollArrayWrapper(int newSize) { 52 newSize = (newSize + 1) * SIZE_POLLFD; 53 pollArray = new AllocatedNativeObject(newSize, false); 54 pollArrayAddress = pollArray.address(); 55 totalChannels = 1; 56 } 57 initInterrupt(int fd0, int fd1)58 void initInterrupt(int fd0, int fd1) { 59 interruptFD = fd1; 60 putDescriptor(0, fd0); 61 putEventOps(0, POLLIN); 62 putReventOps(0, 0); 63 } 64 release(int i)65 void release(int i) { 66 return; 67 } 68 free()69 void free() { 70 pollArray.free(); 71 } 72 73 /** 74 * Prepare another pollfd struct for use. 75 */ addEntry(SelChImpl sc)76 void addEntry(SelChImpl sc) { 77 putDescriptor(totalChannels, IOUtil.fdVal(sc.getFD())); 78 putEventOps(totalChannels, 0); 79 putReventOps(totalChannels, 0); 80 totalChannels++; 81 } 82 83 /** 84 * Writes the pollfd entry from the source wrapper at the source index 85 * over the entry in the target wrapper at the target index. The source 86 * array remains unchanged unless the source array and the target are 87 * the same array. 88 */ replaceEntry(PollArrayWrapper source, int sindex, PollArrayWrapper target, int tindex)89 static void replaceEntry(PollArrayWrapper source, int sindex, 90 PollArrayWrapper target, int tindex) { 91 target.putDescriptor(tindex, source.getDescriptor(sindex)); 92 target.putEventOps(tindex, source.getEventOps(sindex)); 93 target.putReventOps(tindex, source.getReventOps(sindex)); 94 } 95 96 /** 97 * Grows the pollfd array to a size that will accommodate newSize 98 * pollfd entries. This method does no checking of the newSize 99 * to determine if it is in fact bigger than the old size: it 100 * always reallocates an array of the new size. 101 */ grow(int newSize)102 void grow(int newSize) { 103 // create new array 104 PollArrayWrapper temp = new PollArrayWrapper(newSize); 105 106 // Copy over existing entries 107 for (int i=0; i<totalChannels; i++) 108 replaceEntry(this, i, temp, i); 109 110 // Swap new array into pollArray field 111 pollArray.free(); 112 pollArray = temp.pollArray; 113 pollArrayAddress = pollArray.address(); 114 } 115 poll(int numfds, int offset, long timeout)116 int poll(int numfds, int offset, long timeout) { 117 return poll0(pollArrayAddress + (offset * SIZE_POLLFD), 118 numfds, timeout); 119 } 120 interrupt()121 public void interrupt() { 122 interrupt(interruptFD); 123 } 124 poll0(long pollAddress, int numfds, long timeout)125 private native int poll0(long pollAddress, int numfds, long timeout); 126 interrupt(int fd)127 private static native void interrupt(int fd); 128 129 } 130