1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.newsclub.net.unix;
19
20 import java.nio.channels.SelectableChannel;
21 import java.nio.channels.SelectionKey;
22 import java.nio.channels.Selector;
23 import java.nio.channels.spi.AbstractSelectableChannel;
24 import java.util.concurrent.atomic.AtomicBoolean;
25 import java.util.concurrent.atomic.AtomicInteger;
26
27 import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
28
29 final class AFSelectionKey extends SelectionKey {
30 private static final int OP_INVALID = 1 << 7;
31 private final AFSelector sel;
32 private final AFSocketCore core;
33 private final AtomicInteger ops = new AtomicInteger();
34 private final AtomicInteger opsReady = new AtomicInteger(0);
35 private final SelectableChannel chann;
36 private final AtomicBoolean cancelled = new AtomicBoolean();
37
38 AFSelectionKey(AFSelector selector, AbstractSelectableChannel ch, int ops, Object att) {
39 super();
40 this.chann = ch;
41 this.sel = selector;
42 this.ops.set(ops);
43
44 if (ch instanceof AFDatagramChannel<?>) {
45 this.core = ((AFDatagramChannel<?>) ch).getAFCore();
46 } else if (ch instanceof AFSocketChannel<?>) {
47 this.core = ((AFSocketChannel<?>) ch).getAFCore();
48 } else if (ch instanceof AFServerSocketChannel<?>) {
49 this.core = ((AFServerSocketChannel<?>) ch).getAFCore();
50 } else {
51 throw new UnsupportedOperationException("Unsupported channel: " + ch);
52 }
53
54 attach(att);
55 }
56
57 @Override
58 @SuppressFBWarnings("EI_EXPOSE_REP")
59 public SelectableChannel channel() {
60 return chann;
61 }
62
63 @Override
64 @SuppressFBWarnings("EI_EXPOSE_REP")
65 public Selector selector() {
66 return sel;
67 }
68
69 @Override
70 public boolean isValid() {
71 return !hasOpInvalid() && !cancelled.get() && chann.isOpen() && sel.isOpen();
72 }
73
74 boolean isCancelled() {
75 return cancelled.get();
76 }
77
78 boolean hasOpInvalid() {
79 return (opsReady.get() & OP_INVALID) != 0;
80 }
81
82 boolean isSelected() {
83 return readyOps() != 0;
84 }
85
86 @Override
87 public void cancel() {
88 sel.remove(this);
89 cancelNoRemove();
90 }
91
92 void cancelNoRemove() {
93 if (!cancelled.compareAndSet(false, true) || !chann.isOpen()) {
94 return;
95 }
96
97 cancel1();
98 }
99
100 private void cancel1() {
101
102 }
103
104 @Override
105 public int interestOps() {
106 return ops.get();
107 }
108
109 @Override
110 public SelectionKey interestOps(int interestOps) {
111 this.ops.set(interestOps);
112 return this;
113 }
114
115 @Override
116 public int readyOps() {
117 return opsReady.get() & ~OP_INVALID;
118 }
119
120 AFSocketCore getAFCore() {
121 return core;
122 }
123
124 void setOpsReady(int opsReady) {
125 this.opsReady.set(opsReady);
126 }
127
128 @Override
129 public String toString() {
130 return super.toString() + "[" + readyOps() + ";valid=" + isValid() + ";channel=" + channel()
131 + "]";
132 }
133 }