1/*
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.nio.ch;
27
28import java.io.IOException;
29import java.nio.channels.*;
30import java.nio.channels.spi.*;
31import java.util.*;
32import sun.misc.*;
33
34
35/**
36 * An implementation of Selector for Solaris.
37 */
38
39class PollSelectorImpl
40    extends AbstractPollSelectorImpl
41{
42
43    // File descriptors used for interrupt
44    private int fd0;
45    private int fd1;
46
47    // Lock for interrupt triggering and clearing
48    private Object interruptLock = new Object();
49    private boolean interruptTriggered = false;
50
51    /**
52     * Package private constructor called by factory method in
53     * the abstract superclass Selector.
54     */
55    PollSelectorImpl(SelectorProvider sp) {
56        super(sp, 1, 1);
57        long pipeFds = IOUtil.makePipe(false);
58        fd0 = (int) (pipeFds >>> 32);
59        fd1 = (int) pipeFds;
60        pollWrapper = new PollArrayWrapper(INIT_CAP);
61        pollWrapper.initInterrupt(fd0, fd1);
62        channelArray = new SelectionKeyImpl[INIT_CAP];
63    }
64
65    protected int doSelect(long timeout)
66        throws IOException
67    {
68        if (channelArray == null)
69            throw new ClosedSelectorException();
70        processDeregisterQueue();
71        try {
72            begin();
73            pollWrapper.poll(totalChannels, 0, timeout);
74        } finally {
75            end();
76        }
77        processDeregisterQueue();
78        int numKeysUpdated = updateSelectedKeys();
79        if (pollWrapper.getReventOps(0) != 0) {
80            // Clear the wakeup pipe
81            pollWrapper.putReventOps(0, 0);
82            synchronized (interruptLock) {
83                IOUtil.drain(fd0);
84                interruptTriggered = false;
85            }
86        }
87        return numKeysUpdated;
88    }
89
90    protected void implCloseInterrupt() throws IOException {
91        // prevent further wakeup
92        synchronized (interruptLock) {
93            interruptTriggered = true;
94        }
95        FileDispatcherImpl.closeIntFD(fd0);
96        FileDispatcherImpl.closeIntFD(fd1);
97        fd0 = -1;
98        fd1 = -1;
99        pollWrapper.release(0);
100    }
101
102    public Selector wakeup() {
103        synchronized (interruptLock) {
104            if (!interruptTriggered) {
105                pollWrapper.interrupt();
106                interruptTriggered = true;
107            }
108        }
109        return this;
110    }
111
112}
113