--- a/src/java.base/solaris/classes/sun/nio/ch/EventPortWrapper.java Fri Mar 23 18:44:47 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,276 +0,0 @@
-/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.nio.ch;
-
-import java.io.IOException;
-import java.security.AccessController;
-import java.util.BitSet;
-import java.util.HashMap;
-import java.util.Map;
-
-import jdk.internal.misc.Unsafe;
-import sun.security.action.GetIntegerAction;
-import static sun.nio.ch.SolarisEventPort.*;
-
-/**
- * Manages a Solaris event port and manipulates a native array of pollfd structs
- * on Solaris.
- */
-
-class EventPortWrapper {
- private static final Unsafe unsafe = Unsafe.getUnsafe();
- private static final int addressSize = unsafe.addressSize();
-
- // Maximum number of open file descriptors
- static final int OPEN_MAX = IOUtil.fdLimit();
-
- // Maximum number of events to retrive in one call to port_getn
- static final int POLL_MAX = Math.min(OPEN_MAX-1, 1024);
-
- // initial size of the array to hold pending updates
- private final int INITIAL_PENDING_UPDATE_SIZE = 256;
-
- // maximum size of updateArray
- private static final int MAX_UPDATE_ARRAY_SIZE = AccessController.doPrivileged(
- new GetIntegerAction("sun.nio.ch.maxUpdateArraySize", Math.min(OPEN_MAX, 64*1024)));
-
- // special update status to indicate that it should be ignored
- private static final byte IGNORE = -1;
-
- // port file descriptor
- private final int pfd;
-
- // the poll array (populated by port_getn)
- private final long pollArrayAddress;
- private final AllocatedNativeObject pollArray;
-
- // required when accessing the update* fields
- private final Object updateLock = new Object();
-
- // the number of pending updates
- private int updateCount;
-
- // queue of file descriptors with updates pending
- private int[] updateDescriptors = new int[INITIAL_PENDING_UPDATE_SIZE];
-
- // events for file descriptors with registration changes pending, indexed
- // by file descriptor and stored as bytes for efficiency reasons. For
- // file descriptors higher than MAX_UPDATE_ARRAY_SIZE (unlimited case at
- // least then the update is stored in a map.
- private final byte[] eventsLow = new byte[MAX_UPDATE_ARRAY_SIZE];
- private Map<Integer,Byte> eventsHigh;
- // Used by release and updateRegistrations to track whether a file
- // descriptor is registered with /dev/poll.
- private final BitSet registered = new BitSet();
-
- // bit set to indicate if a file descriptor has been visited when
- // processing updates (used to avoid duplicates calls to port_associate)
- private BitSet visited = new BitSet();
-
- EventPortWrapper() throws IOException {
- int allocationSize = POLL_MAX * SIZEOF_PORT_EVENT;
- pollArray = new AllocatedNativeObject(allocationSize, true);
- pollArrayAddress = pollArray.address();
- this.pfd = port_create();
- if (OPEN_MAX > MAX_UPDATE_ARRAY_SIZE)
- eventsHigh = new HashMap<>();
- }
-
- void close() throws IOException {
- port_close(pfd);
- pollArray.free();
- }
-
- private short getSource(int i) {
- int offset = SIZEOF_PORT_EVENT * i + OFFSETOF_SOURCE;
- return pollArray.getShort(offset);
- }
-
- int getEventOps(int i) {
- int offset = SIZEOF_PORT_EVENT * i + OFFSETOF_EVENTS;
- return pollArray.getInt(offset);
- }
-
- int getDescriptor(int i) {
- int offset = SIZEOF_PORT_EVENT * i + OFFSETOF_OBJECT;
- if (addressSize == 4) {
- return pollArray.getInt(offset);
- } else {
- return (int) pollArray.getLong(offset);
- }
- }
-
- private void setDescriptor(int i, int fd) {
- int offset = SIZEOF_PORT_EVENT * i + OFFSETOF_OBJECT;
- if (addressSize == 4) {
- pollArray.putInt(offset, fd);
- } else {
- pollArray.putLong(offset, fd);
- }
- }
-
- private void setUpdate(int fd, byte events) {
- if (fd < MAX_UPDATE_ARRAY_SIZE) {
- eventsLow[fd] = events;
- } else {
- eventsHigh.put(Integer.valueOf(fd), Byte.valueOf(events));
- }
- }
-
- private byte getUpdate(int fd) {
- if (fd < MAX_UPDATE_ARRAY_SIZE) {
- return eventsLow[fd];
- } else {
- Byte result = eventsHigh.get(Integer.valueOf(fd));
- // result should never be null
- return result.byteValue();
- }
- }
-
- int poll(long timeout) throws IOException {
- // update registrations prior to poll
- synchronized (updateLock) {
-
- // process newest updates first
- int i = updateCount - 1;
- while (i >= 0) {
- int fd = updateDescriptors[i];
- if (!visited.get(fd)) {
- short ev = getUpdate(fd);
- if (ev != IGNORE) {
- if (ev == 0) {
- if (registered.get(fd)) {
- port_dissociate(pfd, PORT_SOURCE_FD, (long)fd);
- registered.clear(fd);
- }
- } else {
- if (port_associate(pfd, PORT_SOURCE_FD, (long)fd, ev)) {
- registered.set(fd);
- }
- }
-
- }
- visited.set(fd);
- }
- i--;
- }
- updateCount = 0;
- }
-
- // poll for events
- int numEntries;
- long to = timeout;
- boolean timedPoll = (to > 0);
- do {
- long startTime = timedPoll ? System.currentTimeMillis() : 0;
- numEntries = port_getn(pfd, pollArrayAddress, POLL_MAX, timeout);
- if (numEntries == IOStatus.INTERRUPTED && timedPoll) {
- // timed poll interrupted so need to adjust timeout
- to -= System.currentTimeMillis() - startTime;
- if (to <= 0) {
- // timeout also expired so no retry
- numEntries = 0;
- }
- }
- } while (numEntries == IOStatus.INTERRUPTED);
-
- // after polling we need to queue all polled file descriptors as they
- // are candidates to register for the next poll.
- synchronized (updateLock) {
- for (int i=0; i<numEntries; i++) {
- if (getSource(i) == PORT_SOURCE_USER) {
- interrupted = true;
- setDescriptor(i, -1);
- } else {
- // the default is to re-associate for the next poll
- int fd = getDescriptor(i);
- registered.clear(fd);
- setInterest(fd);
- }
- }
- }
-
- return numEntries;
- }
-
- private void setInterest(int fd) {
- assert Thread.holdsLock(updateLock);
-
- // record the file descriptor and events, expanding the
- // respective arrays first if necessary.
- int oldCapacity = updateDescriptors.length;
- if (updateCount >= oldCapacity) {
- int newCapacity = oldCapacity + INITIAL_PENDING_UPDATE_SIZE;
- int[] newDescriptors = new int[newCapacity];
- System.arraycopy(updateDescriptors, 0, newDescriptors, 0, oldCapacity);
- updateDescriptors = newDescriptors;
- }
- updateDescriptors[updateCount++] = fd;
- visited.clear(fd);
- }
-
- void setInterest(int fd, int mask) {
- synchronized (updateLock) {
- setInterest(fd);
- setUpdate(fd, (byte)mask);
- assert getUpdate(fd) == mask;
- }
- }
-
- void release(int fd) {
- synchronized (updateLock) {
- if (registered.get(fd)) {
- try {
- port_dissociate(pfd, PORT_SOURCE_FD, (long)fd);
- } catch (IOException ioe) {
- throw new InternalError(ioe);
- }
- registered.clear(fd);
- }
- setUpdate(fd, IGNORE);
- }
- }
-
- // -- wakeup support --
-
- private boolean interrupted;
-
- public void interrupt() {
- try {
- port_send(pfd, 0);
- } catch (IOException ioe) {
- throw new InternalError(ioe);
- }
- }
-
- boolean interrupted() {
- return interrupted;
- }
-
- void clearInterrupted() {
- interrupted = false;
- }
-}