Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/nio/ch/Port.java
32288 views
/*1* Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.ch;2627import java.nio.channels.spi.AsynchronousChannelProvider;28import java.nio.channels.*;29import java.io.IOException;30import java.io.Closeable;31import java.io.FileDescriptor;32import java.util.Map;33import java.util.HashMap;34import java.util.concurrent.locks.ReadWriteLock;35import java.util.concurrent.locks.ReentrantReadWriteLock;3637/**38* Base implementation of AsynchronousChannelGroupImpl for Unix systems.39*/4041abstract class Port extends AsynchronousChannelGroupImpl {4243/**44* Implemented by clients registered with this port.45*/46interface PollableChannel extends Closeable {47void onEvent(int events, boolean mayInvokeDirect);48}4950// maps fd to "pollable" channel51protected final ReadWriteLock fdToChannelLock = new ReentrantReadWriteLock();52protected final Map<Integer,PollableChannel> fdToChannel =53new HashMap<Integer,PollableChannel>();545556Port(AsynchronousChannelProvider provider, ThreadPool pool) {57super(provider, pool);58}5960/**61* Register channel identified by its file descriptor62*/63final void register(int fd, PollableChannel ch) {64fdToChannelLock.writeLock().lock();65try {66if (isShutdown())67throw new ShutdownChannelGroupException();68fdToChannel.put(Integer.valueOf(fd), ch);69} finally {70fdToChannelLock.writeLock().unlock();71}72}7374/**75* Callback method for implementations that need special handling when fd is76* removed (currently only needed in the AIX-Port - see AixPollPort.java).77*/78protected void preUnregister(int fd) {79// Do nothing by default.80}8182/**83* Unregister channel identified by its file descriptor84*/85final void unregister(int fd) {86boolean checkForShutdown = false;8788preUnregister(fd);8990fdToChannelLock.writeLock().lock();91try {92fdToChannel.remove(Integer.valueOf(fd));9394// last key to be removed so check if group is shutdown95if (fdToChannel.isEmpty())96checkForShutdown = true;9798} finally {99fdToChannelLock.writeLock().unlock();100}101102// continue shutdown103if (checkForShutdown && isShutdown()) {104try {105shutdownNow();106} catch (IOException ignore) { }107}108}109/**110* Register file descriptor with polling mechanism for given events.111* The implementation should translate the events as required.112*/113abstract void startPoll(int fd, int events);114115@Override116final boolean isEmpty() {117fdToChannelLock.writeLock().lock();118try {119return fdToChannel.isEmpty();120} finally {121fdToChannelLock.writeLock().unlock();122}123}124125@Override126final Object attachForeignChannel(final Channel channel, FileDescriptor fd) {127int fdVal = IOUtil.fdVal(fd);128register(fdVal, new PollableChannel() {129public void onEvent(int events, boolean mayInvokeDirect) { }130public void close() throws IOException {131channel.close();132}133});134return Integer.valueOf(fdVal);135}136137@Override138final void detachForeignChannel(Object key) {139unregister((Integer)key);140}141142@Override143final void closeAllChannels() {144/**145* Close channels in batches of up to 128 channels. This allows close146* to remove the channel from the map without interference.147*/148final int MAX_BATCH_SIZE = 128;149PollableChannel channels[] = new PollableChannel[MAX_BATCH_SIZE];150int count;151do {152// grab a batch of up to 128 channels153fdToChannelLock.writeLock().lock();154count = 0;155try {156for (Integer fd: fdToChannel.keySet()) {157channels[count++] = fdToChannel.get(fd);158if (count >= MAX_BATCH_SIZE)159break;160}161} finally {162fdToChannelLock.writeLock().unlock();163}164165// close them166for (int i=0; i<count; i++) {167try {168channels[i].close();169} catch (IOException ignore) { }170}171} while (count > 0);172}173}174175176