1 /* 2 * Copyright (c) 2020, 2022, 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 package sun.nio.ch; 26 27 import java.io.IOException; 28 import jdk.internal.misc.Unsafe; 29 30 /** 31 * Provides access to WSAPoll. 32 */ 33 class WSAPoll { 34 private static final Unsafe UNSAFE = Unsafe.getUnsafe(); 35 private static final int ADDRESS_SIZE = UNSAFE.addressSize(); 36 37 private WSAPoll() { } 38 39 /** 40 * typedef struct pollfd { 41 * SOCKET fd; 42 * SHORT events; 43 * SHORT revents; 44 * } WSAPOLLFD; 45 */ 46 static { 47 IOUtil.load(); 48 } 49 private static final int SIZE_POLLFD = pollfdSize(); 50 private static final int FD_OFFSET = fdOffset(); 51 private static final int EVENTS_OFFSET = eventsOffset(); 52 private static final int REVENTS_OFFSET = reventsOffset(); 53 54 /** 55 * Allocates a poll array of {@code size} WSAPOLLFD structures. 56 */ 57 static long allocatePollArray(int size) { 58 if (size <= 0) 59 throw new IllegalArgumentException(); 60 return UNSAFE.allocateMemory(size * SIZE_POLLFD); 61 } 62 63 /** 64 * Reallocates a poll array from {@code size} to {@code newSize} 65 * WSAPOLLFD structures. 66 */ 67 static long reallocatePollArray(long address, int size, int newSize) { 68 if (newSize < size) 69 throw new IllegalArgumentException(); 70 long newAddress = allocatePollArray(newSize); 71 UNSAFE.copyMemory(address, newAddress, size * SIZE_POLLFD); 72 UNSAFE.freeMemory(address); 73 return newAddress; 74 } 75 76 /** 77 * Free a poll array. 78 */ 79 static void freePollArray(long address) { 80 UNSAFE.freeMemory(address); 81 } 82 83 static void putDescriptor(long address, int i, int fd) { 84 int offset = SIZE_POLLFD * i + FD_OFFSET; 85 if (ADDRESS_SIZE == 8) { 86 UNSAFE.putLong(address + offset, fd); 87 } else { 88 UNSAFE.putInt(address + offset, fd); 89 } 90 } 91 92 static int getDescriptor(long address, int i) { 93 int offset = SIZE_POLLFD * i + FD_OFFSET; 94 long s; 95 if (ADDRESS_SIZE == 8) { 96 s = UNSAFE.getLong(address + offset); 97 } else { 98 s = UNSAFE.getInt(address + offset); 99 } 100 int fd = (int) s; 101 assert ((long) fd) == s; 102 return fd; 103 } 104 105 static void putEvents(long address, int i, short events) { 106 int offset = SIZE_POLLFD * i + EVENTS_OFFSET; 107 UNSAFE.putShort(address + offset, events); 108 } 109 110 static short getEvents(long address, int i) { 111 int offset = SIZE_POLLFD * i + EVENTS_OFFSET; 112 return UNSAFE.getShort(address + offset); 113 } 114 115 static void putRevents(long address, int i, short revents) { 116 int offset = SIZE_POLLFD * i + REVENTS_OFFSET; 117 UNSAFE.putShort(address + offset, revents); 118 } 119 120 static short getRevents(long address, int i) { 121 int offset = SIZE_POLLFD * i + REVENTS_OFFSET; 122 return UNSAFE.getShort(address + offset); 123 } 124 125 // -- Native methods -- 126 127 private static native int pollfdSize(); 128 129 private static native int fdOffset(); 130 131 private static native int eventsOffset(); 132 133 private static native int reventsOffset(); 134 135 static native int poll(long pollAddress, int numfds, int timeout) 136 throws IOException; 137 }