jdk/src/java.base/solaris/classes/sun/nio/ch/EventPortWrapper.java
author chegar
Wed, 11 Nov 2015 09:19:12 +0000
changeset 33674 566777f73c32
parent 25859 3317bb8137f4
permissions -rw-r--r--
8140606: Update library code to use internal Unsafe Reviewed-by: alanb, mchung, psandoz, weijun
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
12872
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
     1
/*
23010
6dadb192ad81 8029235: Update copyright year to match last edit in jdk8 jdk repository for 2013
lana
parents: 20176
diff changeset
     2
 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
12872
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
     4
 *
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    10
 *
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    15
 * accompanied this code).
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    16
 *
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    20
 *
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    23
 * questions.
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    24
 */
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    25
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    26
package sun.nio.ch;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    27
20176
59b7a49e7f8b 8024883: (se) SelectableChannel.register throws NPE if fd >= 64k (lnx)
alanb
parents: 12872
diff changeset
    28
import java.io.IOException;
59b7a49e7f8b 8024883: (se) SelectableChannel.register throws NPE if fd >= 64k (lnx)
alanb
parents: 12872
diff changeset
    29
import java.security.AccessController;
59b7a49e7f8b 8024883: (se) SelectableChannel.register throws NPE if fd >= 64k (lnx)
alanb
parents: 12872
diff changeset
    30
import java.util.BitSet;
59b7a49e7f8b 8024883: (se) SelectableChannel.register throws NPE if fd >= 64k (lnx)
alanb
parents: 12872
diff changeset
    31
import java.util.HashMap;
59b7a49e7f8b 8024883: (se) SelectableChannel.register throws NPE if fd >= 64k (lnx)
alanb
parents: 12872
diff changeset
    32
import java.util.Map;
59b7a49e7f8b 8024883: (se) SelectableChannel.register throws NPE if fd >= 64k (lnx)
alanb
parents: 12872
diff changeset
    33
33674
566777f73c32 8140606: Update library code to use internal Unsafe
chegar
parents: 25859
diff changeset
    34
import jdk.internal.misc.Unsafe;
20176
59b7a49e7f8b 8024883: (se) SelectableChannel.register throws NPE if fd >= 64k (lnx)
alanb
parents: 12872
diff changeset
    35
import sun.security.action.GetIntegerAction;
12872
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    36
import static sun.nio.ch.SolarisEventPort.*;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    37
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    38
/**
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    39
 * Manages a Solaris event port and manipulates a native array of pollfd structs
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    40
 * on Solaris.
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    41
 */
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    42
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    43
class EventPortWrapper {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    44
    private static final Unsafe unsafe = Unsafe.getUnsafe();
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    45
    private static final int addressSize = unsafe.addressSize();
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    46
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    47
    // Maximum number of open file descriptors
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    48
    static final int   OPEN_MAX     = IOUtil.fdLimit();
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    49
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    50
    // Maximum number of events to retrive in one call to port_getn
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    51
    static final int   POLL_MAX     =  Math.min(OPEN_MAX-1, 1024);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    52
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    53
    // initial size of the array to hold pending updates
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    54
    private final int INITIAL_PENDING_UPDATE_SIZE = 256;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    55
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    56
    // maximum size of updateArray
20176
59b7a49e7f8b 8024883: (se) SelectableChannel.register throws NPE if fd >= 64k (lnx)
alanb
parents: 12872
diff changeset
    57
    private static final int MAX_UPDATE_ARRAY_SIZE = AccessController.doPrivileged(
59b7a49e7f8b 8024883: (se) SelectableChannel.register throws NPE if fd >= 64k (lnx)
alanb
parents: 12872
diff changeset
    58
        new GetIntegerAction("sun.nio.ch.maxUpdateArraySize", Math.min(OPEN_MAX, 64*1024)));
12872
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    59
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    60
    // special update status to indicate that it should be ignored
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    61
    private static final byte IGNORE = -1;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    62
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    63
    // port file descriptor
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    64
    private final int pfd;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    65
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    66
    // the poll array (populated by port_getn)
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    67
    private final long pollArrayAddress;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    68
    private final AllocatedNativeObject pollArray;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    69
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    70
    // required when accessing the update* fields
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    71
    private final Object updateLock = new Object();
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    72
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    73
    // the number of pending updates
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    74
    private int updateCount;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    75
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    76
    // queue of file descriptors with updates pending
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    77
    private int[] updateDescriptors = new int[INITIAL_PENDING_UPDATE_SIZE];
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    78
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    79
    // events for file descriptors with registration changes pending, indexed
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    80
    // by file descriptor and stored as bytes for efficiency reasons. For
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    81
    // file descriptors higher than MAX_UPDATE_ARRAY_SIZE (unlimited case at
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    82
    // least then the update is stored in a map.
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    83
    private final byte[] eventsLow = new byte[MAX_UPDATE_ARRAY_SIZE];
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    84
    private Map<Integer,Byte> eventsHigh;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    85
    // Used by release and updateRegistrations to track whether a file
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    86
    // descriptor is registered with /dev/poll.
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    87
    private final BitSet registered = new BitSet();
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    88
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    89
    // bit set to indicate if a file descriptor has been visited when
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    90
    // processing updates (used to avoid duplicates calls to port_associate)
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    91
    private BitSet visited = new BitSet();
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    92
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    93
    EventPortWrapper() throws IOException {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    94
        int allocationSize = POLL_MAX * SIZEOF_PORT_EVENT;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    95
        pollArray = new AllocatedNativeObject(allocationSize, true);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    96
        pollArrayAddress = pollArray.address();
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    97
        this.pfd = port_create();
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    98
        if (OPEN_MAX > MAX_UPDATE_ARRAY_SIZE)
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
    99
            eventsHigh = new HashMap<>();
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   100
    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   101
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   102
    void close() throws IOException {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   103
        port_close(pfd);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   104
        pollArray.free();
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   105
    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   106
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   107
    private short getSource(int i) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   108
        int offset = SIZEOF_PORT_EVENT * i + OFFSETOF_SOURCE;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   109
        return pollArray.getShort(offset);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   110
    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   111
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   112
    int getEventOps(int i) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   113
        int offset = SIZEOF_PORT_EVENT * i + OFFSETOF_EVENTS;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   114
        return pollArray.getInt(offset);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   115
    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   116
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   117
    int getDescriptor(int i) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   118
        int offset = SIZEOF_PORT_EVENT * i + OFFSETOF_OBJECT;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   119
        if (addressSize == 4) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   120
            return pollArray.getInt(offset);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   121
        } else {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   122
            return (int) pollArray.getLong(offset);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   123
        }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   124
    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   125
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   126
    private void setDescriptor(int i, int fd) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   127
        int offset = SIZEOF_PORT_EVENT * i + OFFSETOF_OBJECT;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   128
        if (addressSize == 4) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   129
            pollArray.putInt(offset, fd);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   130
        } else {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   131
            pollArray.putLong(offset, fd);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   132
        }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   133
    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   134
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   135
    private void setUpdate(int fd, byte events) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   136
        if (fd < MAX_UPDATE_ARRAY_SIZE) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   137
            eventsLow[fd] = events;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   138
        } else {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   139
            eventsHigh.put(Integer.valueOf(fd), Byte.valueOf(events));
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   140
        }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   141
    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   142
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   143
    private byte getUpdate(int fd) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   144
        if (fd < MAX_UPDATE_ARRAY_SIZE) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   145
            return eventsLow[fd];
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   146
        } else {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   147
            Byte result = eventsHigh.get(Integer.valueOf(fd));
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   148
            // result should never be null
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   149
            return result.byteValue();
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   150
        }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   151
    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   152
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   153
    int poll(long timeout) throws IOException {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   154
        // update registrations prior to poll
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   155
        synchronized (updateLock) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   156
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   157
            // process newest updates first
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   158
            int i = updateCount - 1;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   159
            while (i >= 0) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   160
                int fd = updateDescriptors[i];
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   161
                if (!visited.get(fd)) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   162
                    short ev = getUpdate(fd);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   163
                    if (ev != IGNORE) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   164
                        if (ev == 0) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   165
                            if (registered.get(fd)) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   166
                                port_dissociate(pfd, PORT_SOURCE_FD, (long)fd);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   167
                                registered.clear(fd);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   168
                            }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   169
                        } else {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   170
                            if (port_associate(pfd, PORT_SOURCE_FD, (long)fd, ev)) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   171
                                registered.set(fd);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   172
                            }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   173
                        }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   174
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   175
                    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   176
                    visited.set(fd);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   177
                }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   178
                i--;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   179
            }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   180
            updateCount = 0;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   181
        }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   182
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   183
        // poll for events
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   184
        int updated = port_getn(pfd, pollArrayAddress, POLL_MAX, timeout);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   185
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   186
        // after polling we need to queue all polled file descriptors as they
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   187
        // are candidates to register for the next poll.
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   188
        synchronized (updateLock) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   189
            for (int i=0; i<updated; i++) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   190
                if (getSource(i) == PORT_SOURCE_USER) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   191
                    interrupted = true;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   192
                    setDescriptor(i, -1);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   193
                } else {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   194
                    // the default is to re-associate for the next poll
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   195
                    int fd = getDescriptor(i);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   196
                    registered.clear(fd);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   197
                    setInterest(fd);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   198
                }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   199
            }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   200
        }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   201
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   202
        return updated;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   203
    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   204
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   205
    private void setInterest(int fd) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   206
        assert Thread.holdsLock(updateLock);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   207
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   208
        // record the file descriptor and events, expanding the
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   209
        // respective arrays first if necessary.
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   210
        int oldCapacity = updateDescriptors.length;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   211
        if (updateCount >= oldCapacity) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   212
            int newCapacity = oldCapacity + INITIAL_PENDING_UPDATE_SIZE;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   213
            int[] newDescriptors = new int[newCapacity];
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   214
            System.arraycopy(updateDescriptors, 0, newDescriptors, 0, oldCapacity);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   215
            updateDescriptors = newDescriptors;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   216
        }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   217
        updateDescriptors[updateCount++] = fd;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   218
        visited.clear(fd);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   219
    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   220
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   221
    void setInterest(int fd, int mask) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   222
        synchronized (updateLock) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   223
            setInterest(fd);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   224
            setUpdate(fd, (byte)mask);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   225
            assert getUpdate(fd) == mask;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   226
        }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   227
    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   228
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   229
    void release(int fd) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   230
        synchronized (updateLock) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   231
            if (registered.get(fd)) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   232
                try {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   233
                    port_dissociate(pfd, PORT_SOURCE_FD, (long)fd);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   234
                } catch (IOException ioe) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   235
                    throw new InternalError(ioe);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   236
                }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   237
                registered.clear(fd);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   238
            }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   239
            setUpdate(fd, IGNORE);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   240
        }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   241
    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   242
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   243
    // -- wakeup support --
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   244
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   245
    private boolean interrupted;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   246
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   247
    public void interrupt() {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   248
        try {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   249
            port_send(pfd, 0);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   250
        } catch (IOException ioe) {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   251
            throw new InternalError(ioe);
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   252
        }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   253
    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   254
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   255
    boolean interrupted() {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   256
        return interrupted;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   257
    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   258
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   259
    void clearInterrupted() {
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   260
        interrupted = false;
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   261
    }
16fa902b1469 7172826: (se) Selector based on the Solaris event port mechanism
alanb
parents:
diff changeset
   262
}