##### Coverage Report - com.sun.grizzly.DefaultSelectionKeyHandler

Classes in this File | Line Coverage | Branch Coverage | Complexity
DefaultSelectionKeyHandler |
79 % | 67/85
75 % | 30/40
| 0.0;0

1 |  |
     /*
2 |  |
      *
3 |  |
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 |  |
      *
5 |  |
      * Copyright 2007-2008 Sun Microsystems, Inc. All rights reserved.
6 |  |
      *
7 |  |
      * The contents of this file are subject to the terms of either the GNU
8 |  |
      * General Public License Version 2 only ("GPL") or the Common Development
9 |  |
      * and Distribution License("CDDL") (collectively, the "License").  You
10 |  |
      * may not use this file except in compliance with the License. You can obtain
11 |  |
      * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
12 |  |
      * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
13 |  |
      * language governing permissions and limitations under the License.
14 |  |
      *
15 |  |
      * When distributing the software, include this License Header Notice in each
16 |  |
      * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
17 |  |
      * Sun designates this particular file as subject to the "Classpath" exception
18 |  |
      * as provided by Sun in the GPL Version 2 section of the License file that
19 |  |
      * accompanied this code.  If applicable, add the following below the License
20 |  |
      * Header, with the fields enclosed by brackets [] replaced by your own
21 |  |
      * identifying information: "Portions Copyrighted [year]
22 |  |
      * [name of copyright owner]"
23 |  |
      *
24 |  |
      * Contributor(s):
25 |  |
      *
26 |  |
      * If you wish your version of this file to be governed by only the CDDL or
27 |  |
      * only the GPL Version 2, indicate your decision by adding "[Contributor]
28 |  |
      * elects to include this software in this distribution under the [CDDL or GPL
29 |  |
      * Version 2] license."  If you don't indicate a single choice of license, a
30 |  |
      * recipient has the option to distribute your version of this file under
31 |  |
      * either the CDDL, the GPL Version 2 or to extend the choice of license to
32 |  |
      * its licensees as provided above.  However, if you add GPL Version 2 code
33 |  |
      * and therefore, elected the GPL Version 2 license, then the option applies
34 |  |
      * only if the new code is made subject to such option by the copyright
35 |  |
      * holder.
36 |  |
      *
37 |  |
      */
38 |  |
39 |  |
     package com.sun.grizzly;
40 |  |
41 |  |
     import com.sun.grizzly.util.Copyable;
42 |  |
     import com.sun.grizzly.util.SelectionKeyAttachment;
43 |  |
     import java.nio.channels.ClosedChannelException;
44 |  |
     import java.nio.channels.SelectableChannel;
45 |  |
     import java.nio.channels.SelectionKey;
46 |  |
     import java.nio.channels.Selector;
47 |  |
     import java.util.Iterator;
48 |  |
     import java.util.logging.Level;
49 |  |
50 |  |
51 |  |
     /**
52 |  |
      * Default implementation of a SelectionKey Handler. By default, this
53 |  |
      * class will attach a Long to a SelectionKey in order to calculate the
54 |  |
      * time a SelectionKey can stay active. By default, a SelectionKey will be
55 |  |
      * active for 30 seconds. If during that 30 seconds the client isn't pushing
56 |  |
      * bytes (or closing the connection). the SelectionKey will be expired and
57 |  |
      * its channel closed.
58 |  |
      *
59 |  |
      * @author Jeanfrancois Arcand
60 |  |
      */
61 |  |
     public class DefaultSelectionKeyHandler extends BaseSelectionKeyHandler {
62 |  |
63 |  |
64 |  |
         /**
65 |  |
          * Next time the exprireKeys() will delete keys.
66 |  |
          */
67 | 130 |
         protected long nextKeysExpiration = 0;
68 |  |
69 |  |
70 |  |
         /*
71 |  |
          * Number of seconds before idle keep-alive connections expire
72 |  |
          */
73 | 130 |
         protected long timeout = 30 * 1000L;
74 |  |
75 |  |
76 | 127 |
         public DefaultSelectionKeyHandler() {
77 | 127 |
         }
78 |  |
79 |  |
80 |  |
         public DefaultSelectionKeyHandler(SelectorHandler selectorHandler) {
81 | 3 |
             super(selectorHandler);
82 | 3 |
         }
83 |  |
84 |  |
85 |  |
         /**
86 |  |
          * {@inheritDoc}
87 |  |
          */
88 |  |
         @Override
89 |  |
         public void copyTo(Copyable copy) {
90 | 4 |
             super.copyTo(copy);
91 | 4 |
             DefaultSelectionKeyHandler copyHandler = (DefaultSelectionKeyHandler) copy;
92 | 4 |
             copyHandler.timeout = timeout;
93 | 4 |
         }
94 |  |
95 |  |
         /**
96 |  |
          * {@inheritDoc}
97 |  |
          */
98 |  |
         @Override
99 |  |
         public void process(SelectionKey key) {
100 | 119541 |
             super.process(key);
101 | 119541 |
             removeExpirationStamp(key);
102 | 119541 |
         }
103 |  |
104 |  |
         /**
105 |  |
          * {@inheritDoc}
106 |  |
          */
107 |  |
         @Override
108 |  |
         public void postProcess(SelectionKey key) {
109 | 118539 |
             super.postProcess(key);
110 | 118539 |
             addExpirationStamp(key);
111 | 118539 |
         }
112 |  |
113 |  |
114 |  |
         /**
115 |  |
          * {@inheritDoc}
116 |  |
          */
117 |  |
         @Override
118 |  |
         public void register(Iterator<SelectionKey> keyIterator, int selectionKeyOps) {
119 | 0 |
             long currentTime = System.currentTimeMillis();
120 |  |
             SelectionKey key;
121 | 0 |
             while (keyIterator.hasNext()) {
122 | 0 |
                 key = keyIterator.next();
123 | 0 |
                 keyIterator.remove();
124 | 0 |
                 doRegisterKey(key, selectionKeyOps, currentTime);
125 |  |
             }
126 | 0 |
         }
127 |  |
128 |  |
129 |  |
         /**
130 |  |
          * {@inheritDoc}
131 |  |
          */
132 |  |
         @Override
133 |  |
         public void register(SelectionKey key, int selectionKeyOps) {
134 | 489191 |
             doRegisterKey(key, selectionKeyOps, System.currentTimeMillis());
135 | 489191 |
         }
136 |  |
137 |  |
         /**
138 |  |
          * Registers {@link SelectionKey} to handle certain operations
139 |  |
          */
140 |  |
         protected void doRegisterKey(SelectionKey key, int selectionKeyOps,
141 |  |
                 long currentTime) {
142 | 489193 |
             if (!key.isValid()) {
143 | 1 |
                 return;
144 |  |
             }
145 |  |
146 | 489192 |
             key.interestOps(key.interestOps() | selectionKeyOps);
147 | 489192 |
             addExpirationStamp(key);
148 | 489192 |
         }
149 |  |
150 |  |
         /**
151 |  |
          * {@inheritDoc}
152 |  |
          */
153 |  |
         @Override
154 |  |
         public void register(SelectableChannel channel, int ops)
155 |  |
                 throws ClosedChannelException {
156 | 23 |
             if (!channel.isOpen()) {
157 | 0 |
                 return;
158 |  |
             }
159 |  |
160 | 23 |
             Selector selector = selectorHandler.getSelector();
161 | 23 |
             SelectionKey key = channel.keyFor(selector);
162 | 23 |
             long time = System.currentTimeMillis();
163 |  |
164 | 23 |
             if (key == null) {
165 | 21 |
                 key = channel.register(selector, ops, time);
166 |  |
             } else {
167 | 2 |
                 doRegisterKey(key, ops, time);
168 |  |
             }
169 | 23 |
         }
170 |  |
171 |  |
         /**
172 |  |
          * {@inheritDoc}
173 |  |
          */
174 |  |
         @Override
175 |  |
         @SuppressWarnings("empty-statement")
176 |  |
         public void register(SelectionKey key, long currentTime){
177 |  |
            ;
178 | 0 |
         }
179 |  |
180 |  |
181 |  |
         /**
182 |  |
          * @deprecated
183 |  |
          */
184 |  |
         @Override
185 |  |
         @SuppressWarnings("empty-statement")
186 |  |
         public void expire(SelectionKey key, long currentTime) {
187 |  |
             ;
188 | 0 |
         }
189 |  |
190 |  |
191 |  |
         /**
192 |  |
          * {@inheritDoc}
193 |  |
          */
194 |  |
         @Override
195 |  |
         public void expire(Iterator<SelectionKey> iterator) {
196 | 217925 |
             if (timeout <= 0) return;
197 |  |
198 | 217925 |
             long currentTime = System.currentTimeMillis();
199 | 217925 |
             if (currentTime < nextKeysExpiration) {
200 | 217843 |
                 return;
201 |  |
             }
202 | 82 |
             nextKeysExpiration = currentTime + timeout;
203 |  |
204 |  |
205 |  |
             SelectionKey key;
206 | 186 |
             while (iterator.hasNext()) {
207 | 104 |
                 key = iterator.next();
208 |  |
209 | 104 |
                 if (!key.isValid()){
210 | 0 |
                     continue;
211 |  |
                 }
212 |  |
213 |  |
214 | 104 |
                 Long expire = getExpirationStamp(key);
215 | 104 |
                 if (expire != null){
216 | 27 |
                     if (currentTime - expire >= timeout) {
217 | 0 |
                         cancel(key);
218 | 27 |
                     } else if (expire + timeout < nextKeysExpiration) {
219 | 5 |
                         nextKeysExpiration = expire + timeout;
220 |  |
                     }
221 |  |
                 }
222 | 104 |
             }
223 | 82 |
         }
224 |  |
225 |  |
226 |  |
         public long getTimeout() {
227 | 0 |
             return timeout;
228 |  |
         }
229 |  |
230 |  |
231 |  |
         public void setTimeout(long timeout) {
232 | 0 |
             this.timeout = timeout;
233 | 0 |
         }
234 |  |
235 |  |
236 |  |
         /**
237 |  |
          * Removes expiration timeout stamp from the {@link SelectionKey}
238 |  |
          * depending on its attachment
239 |  |
          *
240 |  |
          * @param {@link SelectionKey}
241 |  |
          */
242 |  |
         private void removeExpirationStamp(SelectionKey key) {
243 | 119541 |
             Object attachment = key.attachment();
244 | 119541 |
             if (attachment != null) {
245 | 119539 |
                 if (attachment instanceof Long) {
246 | 17710 |
                     key.attach(null);
247 | 101829 |
                 } else if (attachment instanceof SelectionKeyAttachment) {
248 | 101829 |
                     ((SelectionKeyAttachment) attachment).setTimeout(null);
249 |  |
                 }
250 |  |
             }
251 | 119541 |
         }
252 |  |
253 |  |
         /**
254 |  |
          * Adds expiration timeout stamp to the {@link SelectionKey}
255 |  |
          * depending on its attachment
256 |  |
          *
257 |  |
          * @param {@link SelectionKey}
258 |  |
          */
259 |  |
         private void addExpirationStamp(SelectionKey key) {
260 | 607731 |
             long currentTime = System.currentTimeMillis();
261 | 607731 |
             Object attachment = key.attachment();
262 | 607731 |
             if (attachment == null) {
263 | 17856 |
                 key.attach(currentTime);
264 | 589875 |
             } else if (attachment instanceof SelectionKeyAttachment) {
265 | 573484 |
                 ((SelectionKeyAttachment) attachment).setTimeout(currentTime);
266 |  |
             }
267 | 607731 |
         }
268 |  |
269 |  |
         /**
270 |  |
          * Gets expiration timeout stamp from the {@link SelectionKey}
271 |  |
          * depending on its attachment
272 |  |
          *
273 |  |
          * @param {@link SelectionKey}
274 |  |
          */
275 |  |
         private Long getExpirationStamp(SelectionKey key) {
276 | 104 |
             Object attachment = key.attachment();
277 | 104 |
             if (attachment != null) {
278 |  |
                 try {
279 |  |
280 |  |
                     // This is extremely bad to invoke instanceof here but
281 |  |
                     // since the framework expose the SelectionKey, an application
282 |  |
                     // can always attach an object on the SelectionKey and we
283 |  |
                     // can't predict the type of the attached object.
284 | 64 |
                     if (attachment instanceof Long) {
285 | 24 |
                         return (Long) attachment;
286 | 40 |
                     } else if (attachment instanceof SelectionKeyAttachment) {
287 | 40 |
                         return ((SelectionKeyAttachment) attachment).getTimeout();
288 |  |
                     }
289 | 0 |
                 } catch (ClassCastException ex) {
290 | 0 |
                     if (logger.isLoggable(Level.FINEST)) {
291 | 0 |
                         logger.log(Level.FINEST,
292 |  |
                                 "Invalid SelectionKey attachment", ex);
293 |  |
                     }
294 | 0 |
                 }
295 |  |
             }
296 |  |
297 | 40 |
             return null;
298 |  |
         }
299 |  |
     }