174 private SocketAddress receive(ByteBuffer bb) throws IOException { |
174 private SocketAddress receive(ByteBuffer bb) throws IOException { |
175 if (timeout == 0) { |
175 if (timeout == 0) { |
176 return dc.receive(bb); |
176 return dc.receive(bb); |
177 } |
177 } |
178 |
178 |
179 // Implement timeout with a selector |
|
180 SelectionKey sk = null; |
|
181 Selector sel = null; |
|
182 dc.configureBlocking(false); |
179 dc.configureBlocking(false); |
183 try { |
180 try { |
184 int n; |
181 int n; |
185 SocketAddress sender; |
182 SocketAddress sender; |
186 if ((sender = dc.receive(bb)) != null) |
183 if ((sender = dc.receive(bb)) != null) |
187 return sender; |
184 return sender; |
188 sel = Util.getTemporarySelector(dc); |
|
189 sk = dc.register(sel, SelectionKey.OP_READ); |
|
190 long to = timeout; |
185 long to = timeout; |
191 for (;;) { |
186 for (;;) { |
192 if (!dc.isOpen()) |
187 if (!dc.isOpen()) |
193 throw new ClosedChannelException(); |
188 throw new ClosedChannelException(); |
194 long st = System.currentTimeMillis(); |
189 long st = System.currentTimeMillis(); |
195 int ns = sel.select(to); |
190 int result = dc.poll(PollArrayWrapper.POLLIN, to); |
196 if (ns > 0 && sk.isReadable()) { |
191 if (result > 0 && |
|
192 ((result & PollArrayWrapper.POLLIN) != 0)) { |
197 if ((sender = dc.receive(bb)) != null) |
193 if ((sender = dc.receive(bb)) != null) |
198 return sender; |
194 return sender; |
199 } |
195 } |
200 sel.selectedKeys().remove(sk); |
|
201 to -= System.currentTimeMillis() - st; |
196 to -= System.currentTimeMillis() - st; |
202 if (to <= 0) |
197 if (to <= 0) |
203 throw new SocketTimeoutException(); |
198 throw new SocketTimeoutException(); |
204 |
199 |
205 } |
200 } |
206 } finally { |
201 } finally { |
207 if (sk != null) |
|
208 sk.cancel(); |
|
209 if (dc.isOpen()) |
202 if (dc.isOpen()) |
210 dc.configureBlocking(true); |
203 dc.configureBlocking(true); |
211 if (sel != null) |
|
212 Util.releaseTemporarySelector(sel); |
|
213 } |
204 } |
214 } |
205 } |
215 |
206 |
216 public void receive(DatagramPacket p) throws IOException { |
207 public void receive(DatagramPacket p) throws IOException { |
217 synchronized (dc.blockingLock()) { |
208 synchronized (dc.blockingLock()) { |