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;
21
22 import java.util.Collections;
23 import java.util.List;
24 import java.util.Set;
25 import java.util.concurrent.CopyOnWriteArrayList;
26 import java.util.concurrent.atomic.AtomicBoolean;
27
28 import org.apache.mina.util.ConcurrentHashSet;
29
30
31
32
33
34
35
36
37 public class IoServiceListenerSupport {
38
39
40
41 private final IoService service;
42
43
44
45
46 private final List<IoServiceListener> listeners = new CopyOnWriteArrayList<IoServiceListener>();
47
48
49
50
51 private final Set<IoSession> managedSessions = new ConcurrentHashSet<IoSession>();
52
53
54
55
56 private final Set<IoSession> readOnlyManagedSessions = Collections.unmodifiableSet(managedSessions);
57
58 private final AtomicBoolean activated = new AtomicBoolean();
59 private volatile long activationTime;
60 private volatile int largestManagedSessionCount;
61 private volatile long cumulativeManagedSessionCount;
62
63
64
65
66 public IoServiceListenerSupport(IoService service) {
67 if (service == null) {
68 throw new NullPointerException("service");
69 }
70 this.service = service;
71 }
72
73
74
75
76 public void add(IoServiceListener listener) {
77 listeners.add(listener);
78 }
79
80
81
82
83 public void remove(IoServiceListener listener) {
84 listeners.remove(listener);
85 }
86
87 public long getActivationTime() {
88 return activationTime;
89 }
90
91 public Set<IoSession> getManagedSessions() {
92 return readOnlyManagedSessions;
93 }
94
95 public int getManagedSessionCount() {
96 return managedSessions.size();
97 }
98
99 public int getLargestManagedSessionCount() {
100 return largestManagedSessionCount;
101 }
102
103 public long getCumulativeManagedSessionCount() {
104 return cumulativeManagedSessionCount;
105 }
106
107 public boolean isActive() {
108 return activated.get();
109 }
110
111
112
113
114
115 public void fireServiceActivated() {
116 if (!activated.compareAndSet(false, true)) {
117 return;
118 }
119
120 activationTime = System.currentTimeMillis();
121
122 for (IoServiceListener l : listeners) {
123 l.serviceActivated(service);
124 }
125 }
126
127
128
129
130
131 public void fireServiceIdle(IdleStatus status) {
132 if (!activated.get()) {
133 return;
134 }
135
136 for (IoServiceListener l : listeners) {
137 l.serviceIdle(service, status);
138 }
139 }
140
141
142
143
144
145
146 public void fireServiceDeactivated() {
147 if (!activated.compareAndSet(true, false)) {
148 return;
149 }
150
151 try {
152 for (IoServiceListener l : listeners) {
153 l.serviceDeactivated(service);
154 }
155 } finally {
156 disconnectSessions();
157 }
158 }
159
160
161
162
163 public void fireSessionCreated(IoSession session) {
164 boolean firstSession = false;
165 if (session.getService() instanceof IoConnector) {
166 synchronized (managedSessions) {
167 firstSession = managedSessions.isEmpty();
168 }
169 }
170
171
172 if (!managedSessions.add(session)) {
173 return;
174 }
175
176
177 if (firstSession) {
178 fireServiceActivated();
179 }
180
181
182 session.getFilterChain().fireSessionCreated();
183 session.getFilterChain().fireSessionOpened();
184
185 int managedSessionCount = managedSessions.size();
186 if (managedSessionCount > largestManagedSessionCount) {
187 largestManagedSessionCount = managedSessionCount;
188 }
189 cumulativeManagedSessionCount ++;
190
191
192 for (IoServiceListener l : listeners) {
193 l.sessionCreated(session);
194 }
195 }
196
197
198
199
200 public void fireSessionDestroyed(IoSession session) {
201
202 if (!managedSessions.remove(session)) {
203 return;
204 }
205
206
207 session.getFilterChain().fireSessionClosed();
208
209
210 try {
211 for (IoServiceListener l : listeners) {
212 l.sessionDestroyed(session);
213 }
214 } finally {
215
216 if (session.getService() instanceof IoConnector) {
217 boolean lastSession = false;
218 synchronized (managedSessions) {
219 lastSession = managedSessions.isEmpty();
220 }
221 if (lastSession) {
222 fireServiceDeactivated();
223 }
224 }
225 }
226 }
227
228 private void disconnectSessions() {
229 if (!(service instanceof IoAcceptor)) {
230 return;
231 }
232
233 if (!((IoAcceptor) service).isCloseOnDeactivation()) {
234 return;
235 }
236
237 Object lock = new Object();
238 IoFutureListener<IoFuture> listener = new LockNotifyingListener(lock);
239
240 for (IoSession s : managedSessions) {
241 s.close().addListener(listener);
242 }
243
244 try {
245 synchronized (lock) {
246 while (!managedSessions.isEmpty()) {
247 lock.wait(500);
248 }
249 }
250 } catch (InterruptedException ie) {
251
252 }
253 }
254
255 private static class LockNotifyingListener implements IoFutureListener<IoFuture> {
256 private final Object lock;
257
258 public LockNotifyingListener(Object lock) {
259 this.lock = lock;
260 }
261
262 public void operationComplete(IoFuture future) {
263 synchronized (lock) {
264 lock.notifyAll();
265 }
266 }
267 }
268 }