1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.nio.channels.spi; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.CancelledKeyException; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.ClosedChannelException; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.IllegalBlockingModeException; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.IllegalSelectorException; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.SelectableChannel; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.SelectionKey; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.Selector; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code AbstractSelectableChannel} is the base implementation class for 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * selectable channels. It declares methods for registering, unregistering and 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * closing selectable channels. It is thread-safe. 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class AbstractSelectableChannel extends SelectableChannel { 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final SelectorProvider provider; 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The collection of key. 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private List<SelectionKey> keyList = new ArrayList<SelectionKey>(); 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 455e23b687ef8b3c696d54d1880b454942875665b7Elliott Hughes private final Object blockingLock = new Object(); 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean isBlocking = true; 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new {@code AbstractSelectableChannel}. 51f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param selectorProvider 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the selector provider that creates this channel. 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected AbstractSelectableChannel(SelectorProvider selectorProvider) { 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project provider = selectorProvider; 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the selector provider that has created this channel. 61f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.nio.channels.SelectableChannel#provider() 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this channel's selector provider. 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 65eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson @Override 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final SelectorProvider provider() { 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return provider; 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether this channel is registered with one or more selectors. 72eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this channel is registered with a selector, 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} otherwise. 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 76eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson @Override 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized public final boolean isRegistered() { 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return !keyList.isEmpty(); 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets this channel's selection key for the specified selector. 83eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param selector 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the selector with which this channel has been registered. 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the selection key for the channel or {@code null} if this channel 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * has not been registered with {@code selector}. 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 89eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson @Override 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized public final SelectionKey keyFor(Selector selector) { 91220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes for (SelectionKey key : keyList) { 92b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (key != null && key.selector() == selector) { 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return key; 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Registers this channel with the specified selector for the specified 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * interest set. If the channel is already registered with the selector, the 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link SelectionKey interest set} is updated to {@code interestSet} and 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the corresponding selection key is returned. If the channel is not yet 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * registered, this method calls the {@code register} method of 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code selector} and adds the selection key to this channel's key set. 106f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param selector 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the selector with which to register this channel. 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param interestSet 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this channel's {@link SelectionKey interest set}. 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param attachment 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the object to attach, can be {@code null}. 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the selection key for this registration. 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws CancelledKeyException 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this channel is registered but its key has been canceled. 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClosedChannelException 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this channel is closed. 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code interestSet} is not supported by this channel. 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockingModeException 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this channel is in blocking mode. 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalSelectorException 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this channel does not have the same provider as the given 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * selector. 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 126eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson @Override 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final SelectionKey register(Selector selector, int interestSet, 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object attachment) throws ClosedChannelException { 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isOpen()) { 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClosedChannelException(); 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!((interestSet & ~validOps()) == 0)) { 133cff1616012dc0d56c2da9af2b9b1183e76c7e044Elliott Hughes throw new IllegalArgumentException("no valid ops in interest set: " + interestSet); 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (blockingLock) { 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isBlocking) { 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalBlockingModeException(); 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!selector.isOpen()) { 141b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (interestSet == 0) { 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // throw ISE exactly to keep consistency 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalSelectorException(); 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // throw NPE exactly to keep consistency 146c2d0a1f1bd2c6414c29dd44fe240dcf1f45e59b9Elliott Hughes throw new NullPointerException("selector not open"); 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SelectionKey key = keyFor(selector); 149b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (key == null) { 150b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes key = ((AbstractSelector) selector).register(this, interestSet, attachment); 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project keyList.add(key); 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!key.isValid()) { 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new CancelledKeyException(); 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project key.interestOps(interestSet); 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project key.attach(attachment); 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return key; 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Implements the channel closing behavior. Calls 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code implCloseSelectableChannel()} first, then loops through the list 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of selection keys and cancels them, which unregisters this channel from 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * all selectors it is registered with. 168f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a problem occurs while closing the channel. 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 172eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson @Override 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized protected final void implCloseChannel() throws IOException { 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project implCloseSelectableChannel(); 175220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes for (SelectionKey key : keyList) { 176b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (key != null) { 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project key.cancel(); 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Implements the closing function of the SelectableChannel. This method is 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * called from {@code implCloseChannel()}. 185f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O exception occurs. 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void implCloseSelectableChannel() throws IOException; 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether this channel is in blocking mode. 193eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this channel is blocking, {@code false} 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 197eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson @Override 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final boolean isBlocking() { 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (blockingLock) { 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return isBlocking; 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the object used for the synchronization of {@code register} and 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code configureBlocking}. 207eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the synchronization object. 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 210eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson @Override 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final Object blockingLock() { 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return blockingLock; 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the blocking mode of this channel. A call to this method blocks if 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * other calls to this method or to {@code register} are executing. The 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * actual setting of the mode is done by calling 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code implConfigureBlocking(boolean)}. 220f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 221eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * @see java.nio.channels.SelectableChannel#configureBlocking(boolean) 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param blockingMode 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code true} for setting this channel's mode to blocking, 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} to set it to non-blocking. 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this channel. 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClosedChannelException 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this channel is closed. 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockingModeException 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code block} is {@code true} and this channel has been 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * registered with at least one selector. 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O error occurs. 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 234eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson @Override 2354e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes public final SelectableChannel configureBlocking(boolean blockingMode) throws IOException { 236220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes if (!isOpen()) { 237220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes throw new ClosedChannelException(); 238220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes } 239220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes synchronized (blockingLock) { 240220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes if (isBlocking == blockingMode) { 241220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes return this; 242220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes } 243220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes if (blockingMode && containsValidKeys()) { 244220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes throw new IllegalBlockingModeException(); 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 246220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes implConfigureBlocking(blockingMode); 247220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes isBlocking = blockingMode; 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 249220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes return this; 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 253a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes * Implements the configuration of blocking/non-blocking mode. 254f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 255a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes * @param blocking true for blocking, false for non-blocking. 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O error occurs. 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 259a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes protected abstract void implConfigureBlocking(boolean blocking) throws IOException; 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * package private for deregister method in AbstractSelector. 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized void deregister(SelectionKey k) { 265b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (keyList != null) { 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project keyList.remove(k); 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 270eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson /** 271eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * Returns true if the keyList contains at least 1 valid key and false 272eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * otherwise. 273eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson */ 274eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson private synchronized boolean containsValidKeys() { 275220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes for (SelectionKey key : keyList) { 276eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (key != null && key.isValid()) { 277eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson return true; 278eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } 279eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } 280eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson return false; 281eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 283