1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.common.support;
21
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import org.apache.mina.common.ExceptionMonitor;
26 import org.apache.mina.common.IoFuture;
27 import org.apache.mina.common.IoFutureListener;
28 import org.apache.mina.common.IoSession;
29
30
31
32
33
34
35
36 public class DefaultIoFuture implements IoFuture {
37 private final IoSession session;
38
39 private final Object lock;
40
41 private IoFutureListener firstListener;
42
43 private List<IoFutureListener> otherListeners;
44
45 private Object result;
46
47 private boolean ready;
48
49
50
51
52
53
54 public DefaultIoFuture(IoSession session) {
55 this.session = session;
56 this.lock = this;
57 }
58
59 public IoSession getSession() {
60 return session;
61 }
62
63 public void join() {
64 synchronized (lock) {
65 while (!ready) {
66 try {
67 lock.wait();
68 } catch (InterruptedException e) {
69 }
70 }
71 }
72 }
73
74 public boolean join(long timeoutMillis) {
75 long startTime = (timeoutMillis <= 0) ? 0 : System.currentTimeMillis();
76 long waitTime = timeoutMillis;
77
78 synchronized (lock) {
79 if (ready) {
80 return ready;
81 } else if (waitTime <= 0) {
82 return ready;
83 }
84
85 for (;;) {
86 try {
87 lock.wait(waitTime);
88 } catch (InterruptedException e) {
89 }
90
91 if (ready) {
92 return true;
93 } else {
94 waitTime = timeoutMillis
95 - (System.currentTimeMillis() - startTime);
96 if (waitTime <= 0) {
97 return ready;
98 }
99 }
100 }
101 }
102 }
103
104 public boolean isReady() {
105 synchronized (lock) {
106 return ready;
107 }
108 }
109
110
111
112
113 protected void setValue(Object newValue) {
114 synchronized (lock) {
115
116 if (ready) {
117 return;
118 }
119
120 result = newValue;
121 ready = true;
122 lock.notifyAll();
123
124 notifyListeners();
125 }
126 }
127
128
129
130
131 protected Object getValue() {
132 synchronized (lock) {
133 return result;
134 }
135 }
136
137 public void addListener(IoFutureListener listener) {
138 if (listener == null) {
139 throw new NullPointerException("listener");
140 }
141
142 synchronized (lock) {
143 if (!ready) {
144 if (firstListener == null) {
145 firstListener = listener;
146 } else {
147 if (otherListeners == null) {
148 otherListeners = new ArrayList<IoFutureListener>(1);
149 }
150 otherListeners.add(listener);
151 }
152 } else {
153 notifyListener(listener);
154 }
155 }
156 }
157
158 public void removeListener(IoFutureListener listener) {
159 if (listener == null) {
160 throw new NullPointerException("listener");
161 }
162
163 synchronized (lock) {
164 if (listener == firstListener) {
165 if (otherListeners != null && !otherListeners.isEmpty()) {
166 firstListener = otherListeners.remove(0);
167 } else {
168 firstListener = null;
169 }
170 } else if (otherListeners != null) {
171 otherListeners.remove(listener);
172 }
173 }
174 }
175
176 private void notifyListeners() {
177 synchronized (lock) {
178 if (firstListener != null) {
179 notifyListener(firstListener);
180 if (otherListeners != null) {
181 for (IoFutureListener l : otherListeners) {
182 notifyListener(l);
183 }
184 }
185 }
186 }
187 }
188
189 private void notifyListener(IoFutureListener l) {
190 try {
191 l.operationComplete(this);
192 } catch (Throwable t) {
193 ExceptionMonitor.getInstance().exceptionCaught(t);
194 }
195 }
196 }