1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.core.service;
21
22 import org.apache.mina.core.session.IdleStatus;
23
24
25
26
27
28
29
30
31 public class IoServiceIdleState {
32
33 private AbstractIoService service;
34
35 private int idleTimeForRead;
36 private int idleTimeForWrite;
37 private int idleTimeForBoth;
38
39 private int idleCountForBoth;
40 private int idleCountForRead;
41 private int idleCountForWrite;
42
43 private long lastIdleTimeForBoth;
44 private long lastIdleTimeForRead;
45 private long lastIdleTimeForWrite;
46
47 private final Object idlenessCheckLock = new Object();
48
49 public IoServiceIdleState(AbstractIoService service) {
50 this.service = service;
51 }
52
53
54
55
56
57 public final boolean isIdle(IdleStatus status) {
58 if (status == IdleStatus.BOTH_IDLE) {
59 return idleCountForBoth > 0;
60 }
61
62 if (status == IdleStatus.READER_IDLE) {
63 return idleCountForRead > 0;
64 }
65
66 if (status == IdleStatus.WRITER_IDLE) {
67 return idleCountForWrite > 0;
68 }
69
70 throw new IllegalArgumentException("Unknown idle status: " + status);
71 }
72
73
74
75
76
77 public final boolean isReaderIdle() {
78 return isIdle(IdleStatus.READER_IDLE);
79 }
80
81
82
83
84
85 public final boolean isWriterIdle() {
86 return isIdle(IdleStatus.WRITER_IDLE);
87 }
88
89
90
91
92
93 public final boolean isBothIdle() {
94 return isIdle(IdleStatus.BOTH_IDLE);
95 }
96
97
98
99
100
101
102
103
104
105
106
107 public final int getIdleCount(IdleStatus status) {
108 if (status == IdleStatus.BOTH_IDLE) {
109 return idleCountForBoth;
110 }
111
112 if (status == IdleStatus.READER_IDLE) {
113 return idleCountForRead;
114 }
115
116 if (status == IdleStatus.WRITER_IDLE) {
117 return idleCountForWrite;
118 }
119
120 throw new IllegalArgumentException("Unknown idle status: " + status);
121 }
122
123
124
125
126
127
128 public final int getReaderIdleCount() {
129 return getIdleCount(IdleStatus.READER_IDLE);
130 }
131
132
133
134
135
136
137 public final int getWriterIdleCount() {
138 return getIdleCount(IdleStatus.WRITER_IDLE);
139 }
140
141
142
143
144
145
146 public final int getBothIdleCount() {
147 return getIdleCount(IdleStatus.BOTH_IDLE);
148 }
149
150
151
152
153
154 public final long getLastIdleTime(IdleStatus status) {
155 if (status == IdleStatus.BOTH_IDLE) {
156 return lastIdleTimeForBoth;
157 }
158
159 if (status == IdleStatus.READER_IDLE) {
160 return lastIdleTimeForRead;
161 }
162
163 if (status == IdleStatus.WRITER_IDLE) {
164 return lastIdleTimeForWrite;
165 }
166
167 throw new IllegalArgumentException("Unknown idle status: " + status);
168 }
169
170
171
172
173
174
175 public final long getLastReaderIdleTime() {
176 return getLastIdleTime(IdleStatus.READER_IDLE);
177 }
178
179
180
181
182
183
184 public final long getLastWriterIdleTime() {
185 return getLastIdleTime(IdleStatus.WRITER_IDLE);
186 }
187
188
189
190
191
192
193 public final long getLastBothIdleTime() {
194 return getLastIdleTime(IdleStatus.BOTH_IDLE);
195 }
196
197
198
199
200 public final int getIdleTime(IdleStatus status) {
201 if (status == IdleStatus.BOTH_IDLE) {
202 return idleTimeForBoth;
203 }
204
205 if (status == IdleStatus.READER_IDLE) {
206 return idleTimeForRead;
207 }
208
209 if (status == IdleStatus.WRITER_IDLE) {
210 return idleTimeForWrite;
211 }
212
213 throw new IllegalArgumentException("Unknown idle status: " + status);
214 }
215
216
217
218
219 public final long getIdleTimeInMillis(IdleStatus status) {
220 return getIdleTime(status) * 1000L;
221 }
222
223
224
225
226 public final void setIdleTime(IdleStatus status, int idleTime) {
227 if (idleTime < 0) {
228 throw new IllegalArgumentException("Illegal idle time: " + idleTime);
229 }
230
231 if (status == IdleStatus.BOTH_IDLE) {
232 idleTimeForBoth = idleTime;
233 } else if (status == IdleStatus.READER_IDLE) {
234 idleTimeForRead = idleTime;
235 } else if (status == IdleStatus.WRITER_IDLE) {
236 idleTimeForWrite = idleTime;
237 } else {
238 throw new IllegalArgumentException("Unknown idle status: " + status);
239 }
240
241 if (idleTime == 0) {
242 if (status == IdleStatus.BOTH_IDLE) {
243 idleCountForBoth = 0;
244 } else if (status == IdleStatus.READER_IDLE) {
245 idleCountForRead = 0;
246 } else if (status == IdleStatus.WRITER_IDLE) {
247 idleCountForWrite = 0;
248 }
249 }
250 }
251
252
253
254
255 public final int getReaderIdleTime() {
256 return getIdleTime(IdleStatus.READER_IDLE);
257 }
258
259
260
261
262 public final long getReaderIdleTimeInMillis() {
263 return getIdleTimeInMillis(IdleStatus.READER_IDLE);
264 }
265
266
267
268
269 public final void setReaderIdleTime(int idleTime) {
270 setIdleTime(IdleStatus.READER_IDLE, idleTime);
271 }
272
273
274
275
276 public final int getWriterIdleTime() {
277 return getIdleTime(IdleStatus.WRITER_IDLE);
278 }
279
280
281
282
283 public final long getWriterIdleTimeInMillis() {
284 return getIdleTimeInMillis(IdleStatus.WRITER_IDLE);
285 }
286
287
288
289
290 public final void setWriterIdleTime(int idleTime) {
291 setIdleTime(IdleStatus.WRITER_IDLE, idleTime);
292 }
293
294
295
296
297 public final int getBothIdleTime() {
298 return getIdleTime(IdleStatus.BOTH_IDLE);
299 }
300
301
302
303
304 public final long getBothIdleTimeInMillis() {
305 return getIdleTimeInMillis(IdleStatus.BOTH_IDLE);
306 }
307
308
309
310
311 public final void setBothIdleTime(int idleTime) {
312 setIdleTime(IdleStatus.BOTH_IDLE, idleTime);
313 }
314
315
316
317
318 private void increaseIdleCount(IdleStatus status, long currentTime) {
319 if (status == IdleStatus.BOTH_IDLE) {
320 idleCountForBoth++;
321 lastIdleTimeForBoth = currentTime;
322 } else if (status == IdleStatus.READER_IDLE) {
323 idleCountForRead++;
324 lastIdleTimeForRead = currentTime;
325 } else if (status == IdleStatus.WRITER_IDLE) {
326 idleCountForWrite++;
327 lastIdleTimeForWrite = currentTime;
328 } else {
329 throw new IllegalArgumentException("Unknown idle status: " + status);
330 }
331 }
332
333
334
335
336 public final void notifyIdleness(long currentTime) {
337 IoServiceStatistics stats = (IoServiceStatistics) service.getStatistics();
338 stats.updateThroughput(currentTime);
339
340 synchronized (idlenessCheckLock) {
341 notifyIdleness(currentTime,
342 getIdleTimeInMillis(IdleStatus.BOTH_IDLE),
343 IdleStatus.BOTH_IDLE, Math.max(stats.getLastIoTime(),
344 getLastIdleTime(IdleStatus.BOTH_IDLE)));
345
346 notifyIdleness(currentTime,
347 getIdleTimeInMillis(IdleStatus.READER_IDLE),
348 IdleStatus.READER_IDLE, Math.max(stats.getLastReadTime(),
349 getLastIdleTime(IdleStatus.READER_IDLE)));
350
351 notifyIdleness(currentTime,
352 getIdleTimeInMillis(IdleStatus.WRITER_IDLE),
353 IdleStatus.WRITER_IDLE, Math.max(stats.getLastWriteTime(),
354 getLastIdleTime(IdleStatus.WRITER_IDLE)));
355 }
356 }
357
358
359
360
361 private void notifyIdleness(long currentTime, long idleTime,
362 IdleStatus status, long lastIoTime) {
363 if (idleTime > 0 && lastIoTime != 0
364 && currentTime - lastIoTime >= idleTime) {
365 increaseIdleCount(status, currentTime);
366 service.getListeners().fireServiceIdle(status);
367 }
368 }
369
370
371
372
373 protected void resetIdleCountForRead() {
374 idleCountForBoth = 0;
375 idleCountForRead = 0;
376 }
377
378
379
380
381 protected void resetIdleCountForWrite() {
382 idleCountForBoth = 0;
383 idleCountForWrite = 0;
384 }
385 }