001: /*
002: * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.nio.ch;
027:
028: import java.io.IOException;
029: import java.nio.channels.*;
030: import java.nio.channels.spi.*;
031: import java.util.*;
032: import sun.misc.*;
033:
034: /**
035: * An implementation of Selector for Solaris.
036: */
037:
038: class PollSelectorImpl extends AbstractPollSelectorImpl {
039:
040: // File descriptors used for interrupt
041: private int fd0;
042: private int fd1;
043:
044: // Lock for interrupt triggering and clearing
045: private Object interruptLock = new Object();
046: private boolean interruptTriggered = false;
047:
048: /**
049: * Package private constructor called by factory method in
050: * the abstract superclass Selector.
051: */
052: PollSelectorImpl(SelectorProvider sp) {
053: super (sp, 1, 1);
054: int[] fdes = new int[2];
055: IOUtil.initPipe(fdes, false);
056: fd0 = fdes[0];
057: fd1 = fdes[1];
058: pollWrapper = new PollArrayWrapper(INIT_CAP);
059: pollWrapper.initInterrupt(fd0, fd1);
060: channelArray = new SelectionKeyImpl[INIT_CAP];
061: }
062:
063: protected int doSelect(long timeout) throws IOException {
064: if (channelArray == null)
065: throw new ClosedSelectorException();
066: processDeregisterQueue();
067: try {
068: begin();
069: pollWrapper.poll(totalChannels, 0, timeout);
070: } finally {
071: end();
072: }
073: processDeregisterQueue();
074: int numKeysUpdated = updateSelectedKeys();
075: if (pollWrapper.getReventOps(0) != 0) {
076: // Clear the wakeup pipe
077: pollWrapper.putReventOps(0, 0);
078: synchronized (interruptLock) {
079: IOUtil.drain(fd0);
080: interruptTriggered = false;
081: }
082: }
083: return numKeysUpdated;
084: }
085:
086: protected void implCloseInterrupt() throws IOException {
087: // prevent further wakeup
088: synchronized (interruptLock) {
089: interruptTriggered = true;
090: }
091: FileDispatcher.closeIntFD(fd0);
092: FileDispatcher.closeIntFD(fd1);
093: fd0 = -1;
094: fd1 = -1;
095: pollWrapper.release(0);
096: }
097:
098: public Selector wakeup() {
099: synchronized (interruptLock) {
100: if (!interruptTriggered) {
101: pollWrapper.interrupt();
102: interruptTriggered = true;
103: }
104: }
105: return this;
106: }
107:
108: }
|