1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.http.impl.nio.reactor;
29
30 import java.io.IOException;
31 import java.net.SocketAddress;
32 import java.nio.channels.Channel;
33 import java.nio.channels.SelectionKey;
34
35 import org.apache.http.annotation.ThreadSafe;
36 import org.apache.http.nio.reactor.ListenerEndpoint;
37
38
39
40
41
42
43 @ThreadSafe
44 public class ListenerEndpointImpl implements ListenerEndpoint {
45
46 private volatile boolean completed;
47 private volatile boolean closed;
48 private volatile SelectionKey key;
49 private volatile SocketAddress address;
50 private volatile IOException exception;
51
52 private final ListenerEndpointClosedCallback callback;
53
54 public ListenerEndpointImpl(
55 final SocketAddress address,
56 final ListenerEndpointClosedCallback callback) {
57 super();
58 if (address == null) {
59 throw new IllegalArgumentException("Address may not be null");
60 }
61 this.address = address;
62 this.callback = callback;
63 }
64
65 public SocketAddress getAddress() {
66 return this.address;
67 }
68
69 public boolean isCompleted() {
70 return this.completed;
71 }
72
73 public IOException getException() {
74 return this.exception;
75 }
76
77 public void waitFor() throws InterruptedException {
78 if (this.completed) {
79 return;
80 }
81 synchronized (this) {
82 while (!this.completed) {
83 wait();
84 }
85 }
86 }
87
88 public void completed(final SocketAddress address) {
89 if (address == null) {
90 throw new IllegalArgumentException("Address may not be null");
91 }
92 if (this.completed) {
93 return;
94 }
95 this.completed = true;
96 synchronized (this) {
97 this.address = address;
98 notifyAll();
99 }
100 }
101
102 public void failed(final IOException exception) {
103 if (exception == null) {
104 return;
105 }
106 if (this.completed) {
107 return;
108 }
109 this.completed = true;
110 synchronized (this) {
111 this.exception = exception;
112 notifyAll();
113 }
114 }
115
116 public void cancel() {
117 if (this.completed) {
118 return;
119 }
120 this.completed = true;
121 this.closed = true;
122 synchronized (this) {
123 notifyAll();
124 }
125 }
126
127 protected void setKey(final SelectionKey key) {
128 this.key = key;
129 }
130
131 public boolean isClosed() {
132 return this.closed || (this.key != null && !this.key.isValid());
133 }
134
135 public void close() {
136 if (this.closed) {
137 return;
138 }
139 this.completed = true;
140 this.closed = true;
141 if (this.key != null) {
142 this.key.cancel();
143 Channel channel = this.key.channel();
144 if (channel.isOpen()) {
145 try {
146 channel.close();
147 } catch (IOException ignore) {}
148 }
149 }
150 if (this.callback != null) {
151 this.callback.endpointClosed(this);
152 }
153 synchronized (this) {
154 notifyAll();
155 }
156 }
157
158 }