950
|
1 /*
|
|
2 Thread synchronization in java.nio.channels.Selector is completely fucked up, unsurprisingly since NIO was developed in this demented century. This class works around the modern insanity.
|
|
3 */
|
|
4
|
|
5 package org.eclipse.jetty.io.nio;
|
|
6
|
|
7 import java.io.IOException;
|
|
8 import java.nio.channels.Selector;
|
|
9 import java.nio.channels.SelectionKey;
|
|
10 import java.nio.channels.SelectableChannel;
|
|
11 import java.nio.channels.ClosedChannelException;
|
|
12 import java.util.Set;
|
|
13
|
|
14
|
|
15 public final class SaneSelector {
|
|
16 private final Selector selector;
|
|
17 private boolean inSelect = false;
|
|
18 private boolean inUpdate = false;
|
|
19
|
|
20 public SaneSelector() throws IOException {
|
|
21 selector = Selector.open();
|
|
22 }
|
|
23
|
|
24 public void close() throws IOException {
|
|
25 selector.close();
|
|
26 }
|
|
27
|
|
28 public boolean isOpen() {
|
|
29 return selector.isOpen();
|
|
30 }
|
|
31
|
|
32 public int select() throws IOException {
|
|
33 synchronized(this) {
|
|
34 inSelect = true;
|
|
35 }
|
|
36 try {
|
|
37 while(true) {
|
|
38 int n = selector.select();
|
|
39 synchronized(this) {
|
|
40 boolean wasInUpdate = inUpdate;
|
|
41 inUpdate = false;
|
|
42 if( n > 0 || !wasInUpdate )
|
|
43 return n;
|
|
44 }
|
|
45 }
|
|
46 } finally {
|
|
47 synchronized(this) {
|
|
48 inSelect = false;
|
|
49 }
|
|
50 }
|
|
51 }
|
|
52
|
|
53 public Set<SelectionKey> selectedKeys() {
|
|
54 return selector.selectedKeys();
|
|
55 }
|
|
56
|
|
57 public Set<SelectionKey> keys() {
|
|
58 return selector.keys();
|
|
59 }
|
|
60
|
|
61 public synchronized SelectionKey register(SelectableChannel channel,int ops,Object att) throws ClosedChannelException {
|
|
62 update();
|
|
63 return channel.register(selector,ops,att);
|
|
64 }
|
|
65
|
|
66 public synchronized void update() {
|
|
67 if( inSelect ) {
|
|
68 inUpdate = true;
|
|
69 selector.wakeup();
|
|
70 }
|
|
71 }
|
|
72 } |