001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package java.nio.channels.spi;
019:
020: import java.io.IOException;
021: import java.nio.channels.SelectionKey;
022: import java.nio.channels.Selector;
023: import java.util.HashSet;
024: import java.util.Set;
025:
026: /**
027: * Abstract class for selectors.
028: * <p>
029: * This class realizes the interruption of selection by <code>begin</code> and
030: * <code>end</code>. It also holds the cancelled and the deletion of the key
031: * set.
032: * </p>
033: *
034: */
035: public abstract class AbstractSelector extends Selector {
036: private volatile boolean isOpen = true;
037:
038: private SelectorProvider provider = null;
039:
040: /*
041: * Set of cancelled keys.
042: */
043: private Set<SelectionKey> cancelledKeysSet = new HashSet<SelectionKey>();
044:
045: /**
046: * Constructor for this class.
047: *
048: * @param selectorProvider
049: * A instance of SelectorProvider
050: */
051: protected AbstractSelector(SelectorProvider selectorProvider) {
052: provider = selectorProvider;
053: }
054:
055: /**
056: * Closes this channel.
057: *
058: * @see java.nio.channels.Selector#close()
059: */
060: @Override
061: public synchronized final void close() throws IOException {
062: if (isOpen) {
063: isOpen = false;
064: implCloseSelector();
065: }
066: }
067:
068: /**
069: * Implements the closing of this channel.
070: *
071: * @throws IOException
072: * If some I/O exception occurs.
073: */
074: protected abstract void implCloseSelector() throws IOException;
075:
076: /**
077: * @see java.nio.channels.Selector#isOpen()
078: */
079: @Override
080: public final boolean isOpen() {
081: return isOpen;
082: }
083:
084: /**
085: * Answers the SelectorProvider of this channel.
086: *
087: * @see java.nio.channels.Selector#provider()
088: */
089: @Override
090: public final SelectorProvider provider() {
091: return provider;
092: }
093:
094: /**
095: * Answers the cancelled key set of this channel.
096: *
097: * @return The cancelled key set.
098: */
099: protected final Set<SelectionKey> cancelledKeys() {
100: return cancelledKeysSet;
101: }
102:
103: /**
104: * Registers a channel to this selector.
105: *
106: * @param channel
107: * The channel to be registered.
108: * @param operations
109: * The interest set.
110: * @param attachment
111: * The attachment of the key.
112: * @return The key related with the channel and the selector.
113: */
114: protected abstract SelectionKey register(
115: AbstractSelectableChannel channel, int operations,
116: Object attachment);
117:
118: /**
119: * Deletes the key from channel's key set.
120: *
121: * @param key
122: * The key.
123: */
124: protected final void deregister(AbstractSelectionKey key) {
125: ((AbstractSelectableChannel) key.channel()).deregister(key);
126: key.isValid = false;
127: }
128:
129: protected final void begin() {
130: // FIXME: be accommodate before VM actually provides
131: // setInterruptAction method
132: if (AbstractInterruptibleChannel.setInterruptAction != null) {
133: try {
134: AbstractInterruptibleChannel.setInterruptAction.invoke(
135: Thread.currentThread(),
136: new Object[] { new Runnable() {
137: public void run() {
138: AbstractSelector.this .wakeup();
139: }
140: } });
141: } catch (Exception e) {
142: throw new RuntimeException(e);
143: }
144: }
145: }
146:
147: protected final void end() {
148: // FIXME: be accommodate before VM actually provides
149: // setInterruptAction method
150: if (AbstractInterruptibleChannel.setInterruptAction != null) {
151: try {
152: AbstractInterruptibleChannel.setInterruptAction.invoke(
153: Thread.currentThread(), new Object[] { null });
154: } catch (Exception e) {
155: throw new RuntimeException(e);
156: }
157: }
158: }
159:
160: /*
161: * package private method for AbstractSelectionKey.cancel()
162: */
163: void cancel(SelectionKey key) {
164: synchronized (cancelledKeysSet) {
165: cancelledKeysSet.add(key);
166: }
167: }
168: }
|