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