1 /*
2  * Copyright (c) 2001, 2004, 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 
26 package sun.nio.ch;
27 
28 import sun.misc.*;
29 
30 
31 /**
32  * Manipulates a native array of pollfd structs on Solaris:
33  *
34  * typedef struct pollfd {
35  *    int fd;
36  *    short events;
37  *    short revents;
38  * } pollfd_t;
39  *
40  * @author Mike McCloskey
41  * @since 1.4
42  */
43 
44 class PollArrayWrapper extends AbstractPollArrayWrapper {
45 
46     static final short POLLCONN = POLLOUT;
47 
48     // File descriptor to write for interrupt
49     int interruptFD;
50 
PollArrayWrapper(int newSize)51     PollArrayWrapper(int newSize) {
52         newSize = (newSize + 1) * SIZE_POLLFD;
53         pollArray = new AllocatedNativeObject(newSize, false);
54         pollArrayAddress = pollArray.address();
55         totalChannels = 1;
56     }
57 
initInterrupt(int fd0, int fd1)58     void initInterrupt(int fd0, int fd1) {
59         interruptFD = fd1;
60         putDescriptor(0, fd0);
61         putEventOps(0, POLLIN);
62         putReventOps(0, 0);
63     }
64 
release(int i)65     void release(int i) {
66         return;
67     }
68 
free()69     void free() {
70         pollArray.free();
71     }
72 
73     /**
74      * Prepare another pollfd struct for use.
75      */
addEntry(SelChImpl sc)76     void addEntry(SelChImpl sc) {
77         putDescriptor(totalChannels, IOUtil.fdVal(sc.getFD()));
78         putEventOps(totalChannels, 0);
79         putReventOps(totalChannels, 0);
80         totalChannels++;
81     }
82 
83     /**
84      * Writes the pollfd entry from the source wrapper at the source index
85      * over the entry in the target wrapper at the target index. The source
86      * array remains unchanged unless the source array and the target are
87      * the same array.
88      */
replaceEntry(PollArrayWrapper source, int sindex, PollArrayWrapper target, int tindex)89     static void replaceEntry(PollArrayWrapper source, int sindex,
90                       PollArrayWrapper target, int tindex) {
91         target.putDescriptor(tindex, source.getDescriptor(sindex));
92         target.putEventOps(tindex, source.getEventOps(sindex));
93         target.putReventOps(tindex, source.getReventOps(sindex));
94     }
95 
96     /**
97      * Grows the pollfd array to a size that will accommodate newSize
98      * pollfd entries. This method does no checking of the newSize
99      * to determine if it is in fact bigger than the old size: it
100      * always reallocates an array of the new size.
101      */
grow(int newSize)102     void grow(int newSize) {
103         // create new array
104         PollArrayWrapper temp = new PollArrayWrapper(newSize);
105 
106         // Copy over existing entries
107         for (int i=0; i<totalChannels; i++)
108             replaceEntry(this, i, temp, i);
109 
110         // Swap new array into pollArray field
111         pollArray.free();
112         pollArray = temp.pollArray;
113         pollArrayAddress = pollArray.address();
114     }
115 
poll(int numfds, int offset, long timeout)116     int poll(int numfds, int offset, long timeout) {
117         return poll0(pollArrayAddress + (offset * SIZE_POLLFD),
118                      numfds, timeout);
119     }
120 
interrupt()121     public void interrupt() {
122         interrupt(interruptFD);
123     }
124 
poll0(long pollAddress, int numfds, long timeout)125     private native int poll0(long pollAddress, int numfds, long timeout);
126 
interrupt(int fd)127     private static native void interrupt(int fd);
128 
129 }
130