source: trunk/gcc/libjava/gnu/java/nio/SelectorImpl.java@ 3103

Last change on this file since 3103 was 1389, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 7.9 KB
Line 
1/* SelectorImpl.java --
2 Copyright (C) 2002 Free Software Foundation, Inc.
3
4This file is part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1902111-1307 USA.
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38package gnu.java.nio;
39
40import java.nio.channels.ClosedSelectorException;
41import java.nio.channels.SelectableChannel;
42import java.nio.channels.SelectionKey;
43import java.nio.channels.Selector;
44import java.nio.channels.spi.AbstractSelectableChannel;
45import java.nio.channels.spi.AbstractSelector;
46import java.nio.channels.spi.SelectorProvider;
47import java.util.HashSet;
48import java.util.Iterator;
49import java.util.Set;
50
51public class SelectorImpl extends AbstractSelector
52{
53 boolean closed = false;
54 Set keys, selected, canceled;
55
56 public SelectorImpl (SelectorProvider provider)
57 {
58 super (provider);
59
60 keys = new HashSet ();
61 selected = new HashSet ();
62 canceled = new HashSet ();
63 }
64
65 public Set keys ()
66 {
67 return keys;
68 }
69
70 public int selectNow ()
71 {
72 return select (1);
73 }
74
75 public int select ()
76 {
77 return select (-1);
78 }
79
80 // A timeout value of -1 means block forever.
81 private static native int java_do_select (int[] read, int[] write,
82 int[] except, long timeout);
83
84 private int[] getFDsAsArray (int ops)
85 {
86 int[] result;
87 int counter = 0;
88 Iterator it = keys.iterator ();
89
90 // Count the number of file descriptors needed
91 while (it.hasNext ())
92 {
93 SelectionKeyImpl key = (SelectionKeyImpl) it.next ();
94
95 if ((key.interestOps () & ops) != 0)
96 {
97 counter++;
98 }
99 }
100
101 result = new int[counter];
102
103 counter = 0;
104 it = keys.iterator ();
105
106 // Fill the array with the file descriptors
107 while (it.hasNext ())
108 {
109 SelectionKeyImpl key = (SelectionKeyImpl) it.next ();
110
111 if ((key.interestOps () & ops) != 0)
112 {
113 result[counter] = key.fd;
114 counter++;
115 }
116 }
117
118 return result;
119 }
120
121 public int select (long timeout)
122 {
123 if (closed)
124 {
125 throw new ClosedSelectorException ();
126 }
127
128 if (keys == null)
129 {
130 return 0;
131 }
132
133 int ret = 0;
134
135 deregisterCanceledKeys ();
136
137 // Set only keys with the needed interest ops into the arrays.
138 int[] read = getFDsAsArray (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT);
139 int[] write = getFDsAsArray (SelectionKey.OP_WRITE | SelectionKey.OP_CONNECT);
140 int[] except = new int [0]; // FIXME: We dont need to check this yet
141
142 // Call the native select () on all file descriptors.
143 int anzahl = read.length + write.length + except.length;
144 ret = java_do_select (read, write, except, timeout);
145
146 Iterator it = keys.iterator ();
147
148 while (it.hasNext ())
149 {
150 int ops = 0;
151 SelectionKeyImpl key = (SelectionKeyImpl) it.next ();
152
153 // If key is already selected retrieve old ready ops.
154 if (selected.contains (key))
155 {
156 ops = key.readyOps ();
157 }
158
159 // Set new ready read/accept ops
160 for (int i = 0; i < read.length; i++)
161 {
162 if (key.fd == read[i])
163 {
164 if (key.channel () instanceof ServerSocketChannelImpl)
165 {
166 ops = ops | SelectionKey.OP_ACCEPT;
167 }
168 else
169 {
170 ops = ops | SelectionKey.OP_READ;
171 }
172 }
173 }
174
175 // Set new ready write ops
176 for (int i = 0; i < write.length; i++)
177 {
178 if (key.fd == write[i])
179 {
180 ops = ops | SelectionKey.OP_WRITE;
181
182// if (key.channel ().isConnected ())
183// {
184// ops = ops | SelectionKey.OP_WRITE;
185// }
186// else
187// {
188// ops = ops | SelectionKey.OP_CONNECT;
189// }
190 }
191 }
192
193 // FIXME: We dont handle exceptional file descriptors yet.
194
195 // If key is not yet selected add it.
196 if (!selected.contains (key))
197 {
198 add_selected (key);
199 }
200
201 // Set new ready ops
202 key.readyOps (key.interestOps () & ops);
203 }
204
205 deregisterCanceledKeys ();
206 return ret;
207 }
208
209 public Set selectedKeys ()
210 {
211 return selected;
212 }
213
214 public Selector wakeup ()
215 {
216 return null;
217 }
218
219 public void add (SelectionKeyImpl k)
220 {
221 keys.add (k);
222 }
223
224 void add_selected (SelectionKeyImpl k)
225 {
226 selected.add (k);
227 }
228
229 protected void implCloseSelector ()
230 {
231 closed = true;
232 }
233
234 private void deregisterCanceledKeys ()
235 {
236 Iterator it = canceled.iterator ();
237
238 while (it.hasNext ())
239 {
240 keys.remove ((SelectionKeyImpl) it.next ());
241 it.remove ();
242 }
243 }
244
245 protected SelectionKey register (SelectableChannel ch, int ops, Object att)
246 {
247 return register ((AbstractSelectableChannel) ch, ops, att);
248 }
249
250 protected SelectionKey register (AbstractSelectableChannel ch, int ops,
251 Object att)
252 {
253// // filechannel is not selectable ?
254// if (ch instanceof FileChannelImpl)
255// {
256// FileChannelImpl fc = (FileChannelImpl) ch;
257// SelectionKeyImpl impl = new SelectionKeyImpl (ch, this, fc.fd);
258// keys.add (impl);
259// impl.interestOps (ops);
260// impl.attach (att);
261// return impl;
262// }
263// else
264
265 if (ch instanceof SocketChannelImpl)
266 {
267 SocketChannelImpl sc = (SocketChannelImpl) ch;
268 SelectionKeyImpl impl = new SelectionKeyImpl (ch, this, sc.fd);
269 add (impl);
270 impl.interestOps (ops);
271 impl.attach (att);
272 return impl;
273 }
274 else if (ch instanceof DatagramChannelImpl)
275 {
276 DatagramChannelImpl dc = (DatagramChannelImpl) ch;
277 SelectionKeyImpl impl = new SelectionKeyImpl (ch, this, dc.fd);
278 add (impl);
279 impl.interestOps (ops);
280 impl.attach (att);
281 return impl;
282 }
283 else if (ch instanceof ServerSocketChannelImpl)
284 {
285 ServerSocketChannelImpl ssc = (ServerSocketChannelImpl) ch;
286 SelectionKeyImpl impl = new SelectionKeyImpl (ch, this, ssc.fd);
287 add (impl);
288 impl.interestOps (ops);
289 impl.attach (att);
290 return impl;
291 }
292 else
293 {
294 System.err.println ("INTERNAL ERROR, no known channel type");
295 }
296
297 return null;
298 }
299}
Note: See TracBrowser for help on using the repository browser.