1e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera/* 2e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. 3e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 5e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * This code is free software; you can redistribute it and/or modify it 6e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * under the terms of the GNU General Public License version 2 only, as 7e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * published by the Free Software Foundation. Oracle designates this 8e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * particular file as subject to the "Classpath" exception as provided 9e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * by Oracle in the LICENSE file that accompanied this code. 10e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 11e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * This code is distributed in the hope that it will be useful, but WITHOUT 12e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * version 2 for more details (a copy is included in the LICENSE file that 15e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * accompanied this code). 16e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 17e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * You should have received a copy of the GNU General Public License version 18e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 2 along with this work; if not, write to the Free Software Foundation, 19e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 21e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * or visit www.oracle.com if you need additional information or have any 23e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * questions. 24e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 25e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 26e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmerapackage sun.nio.ch; 27e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 28e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.nio.channels.spi.AsynchronousChannelProvider; 29e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.nio.channels.*; 30e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.io.IOException; 31e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.io.Closeable; 32e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.io.FileDescriptor; 33e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.Map; 34e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.HashMap; 35e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.concurrent.locks.ReadWriteLock; 36e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.concurrent.locks.ReentrantReadWriteLock; 37e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 38e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera/** 39e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Base implementation of AsynchronousChannelGroupImpl for Unix systems. 40e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 41e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 42e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraabstract class Port extends AsynchronousChannelGroupImpl { 43e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 44e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 45e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Implemented by clients registered with this port. 46e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 47e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera interface PollableChannel extends Closeable { 48e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera void onEvent(int events, boolean mayInvokeDirect); 49e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 50e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 51e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // maps fd to "pollable" channel 52e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera protected final ReadWriteLock fdToChannelLock = new ReentrantReadWriteLock(); 53e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera protected final Map<Integer,PollableChannel> fdToChannel = 54e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera new HashMap<Integer,PollableChannel>(); 55e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 56e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 57e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Port(AsynchronousChannelProvider provider, ThreadPool pool) { 58e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera super(provider, pool); 59e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 60e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 61e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 62e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Register channel identified by its file descriptor 63e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 64e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final void register(int fd, PollableChannel ch) { 65e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera fdToChannelLock.writeLock().lock(); 66e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 67e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (isShutdown()) 68e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new ShutdownChannelGroupException(); 69e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera fdToChannel.put(Integer.valueOf(fd), ch); 70e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } finally { 71e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera fdToChannelLock.writeLock().unlock(); 72e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 73e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 74e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 75e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 76519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera * Callback method for implementations that need special handling when fd is 77519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera * removed (currently only needed in the AIX-Port - see AixPollPort.java). 78519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera */ 79519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera protected void preUnregister(int fd) { 80519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera // Do nothing by default. 81519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 82519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 83519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera /** 84e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Unregister channel identified by its file descriptor 85e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 86e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final void unregister(int fd) { 87e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera boolean checkForShutdown = false; 88e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 89519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera preUnregister(fd); 90519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 91e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera fdToChannelLock.writeLock().lock(); 92e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 93e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera fdToChannel.remove(Integer.valueOf(fd)); 94e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 95e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // last key to be removed so check if group is shutdown 96e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (fdToChannel.isEmpty()) 97e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera checkForShutdown = true; 98e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 99e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } finally { 100e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera fdToChannelLock.writeLock().unlock(); 101e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 102e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 103e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // continue shutdown 104e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (checkForShutdown && isShutdown()) { 105e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 106e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera shutdownNow(); 107e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } catch (IOException ignore) { } 108e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 109e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 110e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 111e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Register file descriptor with polling mechanism for given events. 112e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * The implementation should translate the events as required. 113e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 114e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera abstract void startPoll(int fd, int events); 115e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 116e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 117e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final boolean isEmpty() { 118e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera fdToChannelLock.writeLock().lock(); 119e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 120e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return fdToChannel.isEmpty(); 121e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } finally { 122e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera fdToChannelLock.writeLock().unlock(); 123e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 124e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 125e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 126e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 127e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final Object attachForeignChannel(final Channel channel, FileDescriptor fd) { 128e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera int fdVal = IOUtil.fdVal(fd); 129e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera register(fdVal, new PollableChannel() { 130e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public void onEvent(int events, boolean mayInvokeDirect) { } 131e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public void close() throws IOException { 132e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera channel.close(); 133e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 134e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera }); 135e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return Integer.valueOf(fdVal); 136e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 137e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 138e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 139e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final void detachForeignChannel(Object key) { 140e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera unregister((Integer)key); 141e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 142e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 143e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 144e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final void closeAllChannels() { 145e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 146e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Close channels in batches of up to 128 channels. This allows close 147e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * to remove the channel from the map without interference. 148e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 149e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera final int MAX_BATCH_SIZE = 128; 150e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera PollableChannel channels[] = new PollableChannel[MAX_BATCH_SIZE]; 151e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera int count; 152e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera do { 153e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // grab a batch of up to 128 channels 154e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera fdToChannelLock.writeLock().lock(); 155e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera count = 0; 156e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 157e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera for (Integer fd: fdToChannel.keySet()) { 158e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera channels[count++] = fdToChannel.get(fd); 159e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (count >= MAX_BATCH_SIZE) 160e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera break; 161e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 162e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } finally { 163e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera fdToChannelLock.writeLock().unlock(); 164e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 165e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 166e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // close them 167e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera for (int i=0; i<count; i++) { 168e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 169e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera channels[i].close(); 170e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } catch (IOException ignore) { } 171e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 172e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } while (count > 0); 173e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 174e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera} 175