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

Classes in this File | Line Coverage | Branch Coverage | Complexity
Context |
57 % | 89/156
47 % | 24/51
| 0.0;0
Context$1 |
100 % | 1/1
N/A | N/A
| 0.0;0
Context$AsyncQueueReadableContextWrapper |
0 % | 0/7
N/A | N/A
| 0.0;0
Context$AsyncQueueWritableContextWrapper |
29 % | 5/17
N/A | N/A
| 0.0;0
Context$AttributeScope |
100 % | 5/5
N/A | N/A
| 0.0;0
Context$KeyRegistrationState |
100 % | 4/4
N/A | N/A
| 0.0;0
Context$OpType |
100 % | 5/5
N/A | N/A
| 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.async.AsyncQueueDataProcessor;
42 |  |
     import com.sun.grizzly.async.AsyncQueueReadable;
43 |  |
     import com.sun.grizzly.async.AsyncQueueReader;
44 |  |
     import com.sun.grizzly.async.AsyncQueueWritable;
45 |  |
     import com.sun.grizzly.async.AsyncQueueWriter;
46 |  |
     import com.sun.grizzly.async.AsyncReadCallbackHandler;
47 |  |
     import com.sun.grizzly.async.AsyncReadCondition;
48 |  |
     import com.sun.grizzly.async.AsyncWriteCallbackHandler;
49 |  |
     import com.sun.grizzly.util.AttributeHolder;
50 |  |
     import com.sun.grizzly.util.Copyable;
51 |  |
     import com.sun.grizzly.util.SelectionKeyAttachment;
52 |  |
     import com.sun.grizzly.util.WorkerThread;
53 |  |
     import java.io.IOException;
54 |  |
     import java.net.SocketAddress;
55 |  |
     import java.nio.ByteBuffer;
56 |  |
     import java.nio.channels.SelectionKey;
57 |  |
     import java.util.HashMap;
58 |  |
     import java.util.Map;
59 |  |
     import java.util.concurrent.atomic.AtomicInteger;
60 |  |
     import java.util.logging.Level;
61 |  |
62 |  |
     /**
63 |  |
      * This Object is used to share information between the Grizzly Framework
64 |  |
      * classes and {@link ProtocolFilter} implementation. Since {@link Context}
65 |  |
      * is a pooled resource
66 |  |
      * {@link Controller#pollContext(java.nio.channels.SelectionKey)}
67 |  |
      * transactions using {@link Context} outside its {@link ProtocolChain}
68 |  |
      * must invoke {@link #incrementRefCount()} and
69 |  |
      * {@link Controller#returnContext(com.sun.grizzly.Context)} to keep its pooling
70 |  |
      * intact.
71 |  |
      * @author Jeanfrancois Arcand
72 |  |
      */
73 | 173324 |
     public class Context implements AttributeHolder, Copyable {
74 |  |
75 |  |
76 | 6 |
         public enum AttributeScope {
77 | 1 |
             REQUEST,
78 | 1 |
             CONNECTION,
79 | 1 |
             SELECTOR,
80 | 1 |
             CONTROLLER
81 |  |
         }
82 |  |
83 |  |
         /**
84 |  |
          * A {@link SelectionKey}'s registration state.
85 |  |
          */
86 | 4 |
         public enum KeyRegistrationState {
87 |  |
             /** A cancelled {@link SelectionKey} registration state. */
88 | 1 |
             CANCEL,
89 |  |
             /** A registered {@link SelectionKey} registration state. */
90 | 1 |
             REGISTER,
91 |  |
             /** A {@link SelectionKey} with no registration state. */
92 | 1 |
             NONE }
93 |  |
94 |  |
95 |  |
         /**
96 |  |
          * The list of possible {@link SelectionKey}.OP_XXXX.
97 |  |
          */
98 | 7 |
         public enum OpType { OP_READ,
99 | 1 |
             OP_WRITE,
100 | 1 |
             OP_CONNECT,
101 | 1 |
             OP_READ_WRITE,
102 | 1 |
             OP_ACCEPT
103 |  |
         }
104 |  |
105 |  |
106 |  |
         /**
107 |  |
          * The current {@link SelectionKey} interest ops this Context is processing.
108 |  |
          */
109 |  |
         private OpType currentOpType;
110 |  |
111 |  |
112 |  |
         /**
113 |  |
          * The {@link ProtocolChain} used to execute this {@link Context}
114 |  |
          */
115 |  |
         private ProtocolChain protocolChain;
116 |  |
117 |  |
118 |  |
         /**
119 |  |
          * Constant 'throwable' String
120 |  |
          */
121 |  |
         public final static String THROWABLE ="throwable";
122 |  |
123 |  |
124 |  |
         /**
125 |  |
          * Used to share object between {@link ProtocolFilter}.
126 |  |
          * WARNING: Attributes which are added are never removed automatically
127 |  |
          * The removal operation must be done explicitly inside a  {@link ProtocolFilter}.
128 |  |
          */
129 | 261 |
         private Map<String,Object> attributes = null;
130 |  |
131 |  |
132 |  |
         /**
133 |  |
          * The current connection (@link SelectionKey}.
134 |  |
          */
135 |  |
         private SelectionKey key;
136 |  |
137 |  |
138 |  |
         /**
139 |  |
          * The {@link SelectorHandler} associated with this Context.
140 |  |
          */
141 |  |
         private SelectorHandler selectorHandler;
142 |  |
143 |  |
144 |  |
         /**
145 |  |
          * The {@link Controller} associated with this Context.
146 |  |
          */
147 |  |
         private Controller controller;
148 |  |
149 |  |
150 |  |
         /**
151 |  |
          * The state's of the key registration.
152 |  |
          */
153 | 261 |
         private KeyRegistrationState keyRegistrationState
154 |  |
                 = KeyRegistrationState.REGISTER;
155 |  |
156 |  |
157 |  |
         /**
158 |  |
          * The current {@linl Pipeline} that execute this object.
159 |  |
          */
160 |  |
         private Pipeline pipeline;
161 |  |
162 |  |
163 |  |
         /**
164 |  |
          * An optional {@link IOEvent} that can be invoked
165 |  |
          * before the {@link ProtocolChain} is invoked.
166 |  |
          */
167 |  |
         private IOEvent<Context> ioEvent;
168 |  |
169 |  |
170 |  |
         /**
171 |  |
          * {@link AsyncQueueReader}
172 |  |
          */
173 |  |
         private AsyncQueueReader asyncQueueReader;
174 |  |
175 |  |
         /**
176 |  |
          * {@link AsyncQueueWriter}
177 |  |
          */
178 |  |
         private AsyncQueueWriter asyncQueueWriter;
179 |  |
180 |  |
         /**
181 |  |
          * {@link AsyncQueueReadable}
182 |  |
          */
183 |  |
         private AsyncQueueReadable asyncQueueReadable;
184 |  |
185 |  |
         /**
186 |  |
          * {@link AsyncQueueWritable}
187 |  |
          */
188 |  |
         private AsyncQueueWritable asyncQueueWritable;
189 |  |
190 |  |
191 |  |
         /**
192 |  |
          * Is this context suspended.
193 |  |
          */
194 | 261 |
         private boolean isSuspended = false;
195 |  |
196 |  |
          /**
197 |  |
          *  Reference Counter indicating how many Threads share this Context.
198 |  |
          *  Starts at one already counting {@link WorkerThread}.
199 |  |
          */
200 | 261 |
         private AtomicInteger refCounter=new AtomicInteger(1);
201 |  |
202 |  |
203 |  |
         /**
204 |  |
          * Constructor
205 |  |
          */
206 | 261 |
         public Context() {
207 | 261 |
         }
208 |  |
209 |  |
210 |  |
         public void copyTo(Copyable copy) {
211 | 0 |
             Context copyContext = (Context) copy;
212 | 0 |
             copyContext.currentOpType = currentOpType;
213 | 0 |
             copyContext.protocolChain = protocolChain;
214 | 0 |
             if (attributes != null) {
215 | 0 |
                 copyContext.attributes = new HashMap<String, Object>(attributes);
216 |  |
             }
217 | 0 |
             copyContext.key = key;
218 | 0 |
             copyContext.selectorHandler = selectorHandler;
219 | 0 |
             copyContext.controller = controller;
220 | 0 |
             copyContext.keyRegistrationState = keyRegistrationState;
221 | 0 |
             copyContext.pipeline = pipeline;
222 | 0 |
             copyContext.ioEvent = ioEvent;
223 | 0 |
             copyContext.asyncQueueReader = asyncQueueReader;
224 | 0 |
             copyContext.asyncQueueWriter = asyncQueueWriter;
225 | 0 |
         }
226 |  |
227 |  |
         /**
228 |  |
          * Remove a key/value object.
229 |  |
          * @param key - name of an attribute
230 |  |
          * @return  attribute which has been removed
231 |  |
          */
232 |  |
         public Object removeAttribute(String key){
233 | 165998 |
             if (attributes == null){
234 | 56606 |
                 return null;
235 |  |
             }
236 | 109392 |
             return attributes.remove(key);
237 |  |
         }
238 |  |
239 |  |
240 |  |
         /**
241 |  |
          * Set a key/value object.
242 |  |
          * @param key - name of an attribute
243 |  |
          * @param value - value of named attribute
244 |  |
          */
245 |  |
         public void setAttribute(String key,Object value){
246 | 21124 |
             if (attributes == null){
247 | 41 |
                 attributes = new HashMap<String,Object>();
248 |  |
             }
249 | 21124 |
             attributes.put(key,value);
250 | 21124 |
         }
251 |  |
252 |  |
253 |  |
         /**
254 |  |
          * Return an object based on a key.
255 |  |
          * @param key - name of an attribute
256 |  |
          * @return - attribute value for the <tt>key</tt>, null if <tt>key</tt>
257 |  |
          *           does not exist in <tt>attributes</tt>
258 |  |
          */
259 |  |
         public Object getAttribute(String key){
260 | 21006 |
             if (attributes == null){
261 | 1 |
                 return null;
262 |  |
             }
263 | 21005 |
             return attributes.get(key);
264 |  |
         }
265 |  |
266 |  |
267 |  |
         /**
268 |  |
          * Return {@link AttributeHolder}, which corresponds to the
269 |  |
          * given {@link AttributeScope}>
270 |  |
          *
271 |  |
          * @param scope - {@link AttributeScope}>
272 |  |
          * @return - {@link AttributeHolder} instance, which contains
273 |  |
          *           {@link AttributeScope}> attributes
274 |  |
          */
275 |  |
         public AttributeHolder getAttributeHolderByScope(AttributeScope scope){
276 | 52743 |
             AttributeHolder holder = null;
277 | 1 |
             switch(scope) {
278 |  |
                 case REQUEST:
279 | 0 |
                     holder = this;
280 | 0 |
                     break;
281 |  |
                 case CONNECTION:
282 | 52743 |
                     Object attachment = getSelectionKey().attachment();
283 | 52743 |
                     if (attachment instanceof AttributeHolder) {
284 | 52742 |
                         holder = (AttributeHolder) attachment;
285 |  |
                     }
286 |  |
                     break;
287 |  |
                 case SELECTOR:
288 | 0 |
                     holder = selectorHandler;
289 | 0 |
                     break;
290 |  |
                 case CONTROLLER:
291 | 0 |
                     holder = controller;
292 |  |
                     break;
293 |  |
             }
294 |  |
295 | 52743 |
             return holder;
296 |  |
         }
297 |  |
298 |  |
299 |  |
         /**
300 |  |
          * Set a {@link Map} of attribute name/value pairs.
301 |  |
          * Old {@link AttributeHolder} values will not be available.
302 |  |
          * Later changes of this {@link Map} will lead to changes to the current
303 |  |
          * {@link AttributeHolder}.
304 |  |
          *
305 |  |
          * @param attributes - map of name/value pairs
306 |  |
          */
307 |  |
         public void setAttributes(Map<String, Object> attributes) {
308 | 0 |
             this.attributes = attributes;
309 | 0 |
         }
310 |  |
311 |  |
312 |  |
         /**
313 |  |
          * Return a {@link Map} of attribute name/value pairs.
314 |  |
          * Updates, performed on the returned {@link Map} will be reflected in
315 |  |
          * this {@link AttributeHolder}
316 |  |
          *
317 |  |
          * @return - {@link Map} of attribute name/value pairs
318 |  |
          */
319 |  |
         public Map<String, Object> getAttributes() {
320 | 0 |
             return attributes;
321 |  |
         }
322 |  |
323 |  |
324 |  |
         /**
325 |  |
          * Return the current {@link SelectionKey}.
326 |  |
          * @return - this Context's SelectionKey
327 |  |
          */
328 |  |
         public SelectionKey getSelectionKey() {
329 | 619960 |
             return key;
330 |  |
         }
331 |  |
332 |  |
333 |  |
         /**
334 |  |
          * Set the connection {@link SelectionKey}.
335 |  |
          * @param key - set this Context's SelectionKey
336 |  |
          */
337 |  |
         public void setSelectionKey(SelectionKey key) {
338 | 231945 |
             this.key = key;
339 | 231945 |
         }
340 |  |
341 |  |
342 |  |
         /**
343 |  |
          * Return the current {@link Controller}.
344 |  |
          * @return - this Context's current {@link Controller}
345 |  |
          */
346 |  |
         public Controller getController() {
347 | 302630 |
             return controller;
348 |  |
         }
349 |  |
350 |  |
351 |  |
         /**
352 |  |
          * Set the current {@link Controller}.
353 |  |
          * @param {@link Controller}
354 |  |
          */
355 |  |
         public void setController(Controller controller) {
356 | 427668 |
             this.controller = controller;
357 | 427668 |
         }
358 |  |
359 |  |
360 |  |
         /**
361 |  |
          * Recycle this instance.
362 |  |
          */
363 |  |
         public void recycle(){
364 | 161370 |
             if (isSuspended){
365 | 0 |
                 throw new IllegalStateException("The Context has been marked as " +
366 |  |
                         "suspended and cannot be recycled");
367 |  |
             }
368 |  |
369 | 161370 |
             getProtocolChainInstanceHandler().offer(protocolChain);
370 | 161370 |
             key = null;
371 | 161370 |
             keyRegistrationState = KeyRegistrationState.REGISTER;
372 | 161370 |
             currentOpType = null;
373 | 161369 |
             protocolChain = null;
374 | 161368 |
             ioEvent = null;
375 | 161370 |
             asyncQueueReader = null;
376 | 161370 |
             asyncQueueWriter = null;
377 | 161370 |
             if (attributes != null) {
378 | 128305 |
                 attributes.clear();
379 |  |
             }
380 | 161370 |
             isSuspended = false;
381 | 161370 |
             refCounter.set(1);
382 | 161370 |
         }
383 |  |
384 |  |
385 |  |
         /**
386 |  |
          * Return {@link SelectionKey}'s next registration state.
387 |  |
          * @return this Context's SelectionKey registration state
388 |  |
          */
389 |  |
         public KeyRegistrationState getKeyRegistrationState() {
390 | 143908 |
             return keyRegistrationState;
391 |  |
         }
392 |  |
393 |  |
394 |  |
         /**
395 |  |
          * Set the {@link SelectionKey}'s next registration state
396 |  |
          * @param {@link keyRegistrationState} - set this Context's SelectionKey
397 |  |
          *        registration state
398 |  |
          */
399 |  |
         public void setKeyRegistrationState(KeyRegistrationState keyRegistrationState) {
400 | 53253 |
             this.keyRegistrationState = keyRegistrationState;
401 | 53253 |
         }
402 |  |
403 |  |
404 |  |
         /**
405 |  |
          * Return {@link ProtocolChain} executed by this instance.
406 |  |
          * @return {@link ProtocolChain} instance
407 |  |
          */
408 |  |
         public ProtocolChain getProtocolChain() {
409 | 107406 |
             return protocolChain;
410 |  |
         }
411 |  |
412 |  |
413 |  |
         /**
414 |  |
          * Set the {@link ProtocolChain} used by this {@link Context}.
415 |  |
          * @param protocolChain instance of {@link ProtocolChain} to be used by the Context
416 |  |
          */
417 |  |
         public void setProtocolChain(ProtocolChain protocolChain) {
418 | 70566 |
             this.protocolChain = protocolChain;
419 | 70566 |
         }
420 |  |
421 |  |
422 |  |
         /**
423 |  |
          * Get the current {@link SelectionKey} interest ops this instance is executing.
424 |  |
          * @return OpType the currentOpType.
425 |  |
          */
426 |  |
         public OpType getCurrentOpType() {
427 | 96226 |
             return currentOpType;
428 |  |
         }
429 |  |
430 |  |
431 |  |
         /**
432 |  |
          * Set the current OpType value.
433 |  |
          * @param currentOpType sets current operation type
434 |  |
          */
435 |  |
         public void setCurrentOpType(OpType currentOpType) {
436 | 161367 |
             this.currentOpType = currentOpType;
437 | 161367 |
         }
438 |  |
439 |  |
440 |  |
         /**
441 |  |
          * Configure the {@link #currentOpType} based on the
442 |  |
          * {@link SelectionKey#readyOps()} values.
443 |  |
          * @param key
444 |  |
          */
445 |  |
         protected void configureOpType(SelectionKey key) {
446 | 12 |
             int readyOps = key.readyOps();
447 | 12 |
             switch (readyOps){
448 |  |
                 case SelectionKey.OP_CONNECT:
449 | 0 |
                     currentOpType = OpType.OP_CONNECT;
450 | 0 |
                     break;
451 |  |
                 case SelectionKey.OP_READ:
452 | 12 |
                     currentOpType = OpType.OP_READ;
453 | 12 |
                     break;
454 |  |
                 case SelectionKey.OP_WRITE:
455 | 0 |
                     currentOpType = OpType.OP_WRITE;
456 | 0 |
                     break;
457 |  |
                 case (SelectionKey.OP_WRITE | SelectionKey.OP_READ):
458 | 0 |
                     currentOpType = OpType.OP_READ_WRITE;
459 | 0 |
                     break;
460 |  |
                  case (SelectionKey.OP_ACCEPT):
461 | 0 |
                     currentOpType = OpType.OP_ACCEPT;
462 | 0 |
                     break;
463 |  |
                 /**
464 |  |
                  * Fallback to an upcoming OP_CONNECT ops. This happens
465 |  |
                  * because the {@link SocketChannel#finishConnect()} has not yet
466 |  |
                  * been invoked.
467 |  |
                  *
468 |  |
                  */
469 |  |
                 default:
470 | 0 |
                     currentOpType = OpType.OP_CONNECT;
471 |  |
                     break;
472 |  |
473 |  |
             }
474 | 12 |
         }
475 |  |
476 |  |
477 |  |
478 |  |
         /**
479 |  |
          * Execute this Context using the Controller's Pipeline
480 |  |
          * @throws {@link PipelineFullException}
481 |  |
          * @deprecated
482 |  |
          */
483 |  |
         public void execute() throws PipelineFullException {
484 |  |
             // If a IOEvent has been defined, invoke it first and
485 |  |
             // let its associated CallbackHandler decide if the ProtocolChain
486 |  |
             // be invoked or not.
487 | 0 |
             Object attachment = SelectionKeyAttachment.getAttachment(key);
488 | 0 |
             if (ioEvent != null && (attachment instanceof CallbackHandler)) {
489 | 0 |
                 CallbackHandlerContextTask task = CallbackHandlerContextTask.poll();
490 | 0 |
                 task.setCallBackHandler((CallbackHandler) attachment);
491 | 0 |
                 execute(task);
492 | 0 |
             } else {
493 | 0 |
                 execute(ProtocolChainContextTask.poll());
494 |  |
             }
495 | 0 |
         }
496 |  |
497 |  |
498 |  |
         /**
499 |  |
          * Execute this Context using the Controller's Pipeline
500 |  |
          * @param contextTask {@link ContextTask}, which will be
501 |  |
          *                    executed by {@link Pipeline}
502 |  |
          * @throws {@link PipelineFullException}
503 |  |
          */
504 |  |
         public void execute(ContextTask contextTask) throws PipelineFullException {
505 | 102744 |
             execute(contextTask, true);
506 | 102744 |
         }
507 |  |
508 |  |
509 |  |
         /**
510 |  |
          * Execute this Context using either Controller's Pipeline or current thread
511 |  |
          * @param contextTask {@link ContextTask}, which will be
512 |  |
          *                    executed by {@link Pipeline}
513 |  |
          * @param runInSeparateThread if true - {@link ContextTask} will
514 |  |
          *      be executed in separate thread, false - in current thread.
515 |  |
          * @throws {@link PipelineFullException}
516 |  |
          */
517 |  |
         @SuppressWarnings("unchecked")
518 |  |
         public void execute(ContextTask contextTask, boolean runInSeparateThread) throws PipelineFullException {
519 | 161370 |
             if (protocolChain == null){
520 |  |
                 ProtocolChainInstanceHandler
521 | 90804 |
                         pciHandler = getProtocolChainInstanceHandler();
522 | 90804 |
                 protocolChain = pciHandler.poll();
523 |  |
             }
524 |  |
525 | 161370 |
             if (contextTask != null) {
526 | 161370 |
                 contextTask.setContext(this);
527 | 161370 |
                 if (runInSeparateThread) {
528 | 161370 |
                     getPipeline().execute(contextTask);
529 |  |
                 } else {
530 |  |
                     try {
531 | 0 |
                         contextTask.call();
532 | 0 |
                     } catch(Exception e) {
533 | 0 |
                         Controller.logger().log(Level.SEVERE,
534 |  |
                                 "Unexpected exception occured, when executing task: " +
535 |  |
                                 contextTask, e);
536 | 0 |
                     }
537 |  |
                 }
538 |  |
             }
539 | 161370 |
         }
540 |  |
541 |  |
542 |  |
         /**
543 |  |
          * Return the {@link ProtocolChainInstanceListener} associated with this
544 |  |
          * {@link Context}
545 |  |
          * @return ProtocolChainInstanceListener
546 |  |
          */
547 |  |
         public ProtocolChainInstanceHandler getProtocolChainInstanceHandler() {
548 | 252174 |
             ProtocolChainInstanceHandler protocolChainInstanceHandler =
549 |  |
                    selectorHandler.getProtocolChainInstanceHandler();
550 | 252173 |
             return protocolChainInstanceHandler != null ?
551 |  |
                protocolChainInstanceHandler :
552 |  |
                controller.getProtocolChainInstanceHandler();
553 |  |
         }
554 |  |
555 |  |
556 |  |
         /**
557 |  |
          * Return the {@link Pipeline} executing this instance.
558 |  |
          * @return {@link Pipeline}
559 |  |
          */
560 |  |
         public Pipeline getPipeline() {
561 | 161370 |
             if (pipeline == null && controller != null){
562 | 90874 |
                 pipeline = controller.getPipeline();
563 |  |
             }
564 | 161370 |
             return pipeline;
565 |  |
         }
566 |  |
567 |  |
568 |  |
         /**
569 |  |
          * Set the {@link Pipeline} that will execute this instance.
570 |  |
          * @param pipeline  the {@link Pipeline} to set
571 |  |
          */
572 |  |
         public void setPipeline(Pipeline pipeline) {
573 | 90804 |
             this.pipeline = pipeline;
574 | 90804 |
         }
575 |  |
576 |  |
577 |  |
         /**
578 |  |
          * Set an optional CallbackHandler.
579 |  |
          * @param ioEvent  the {@link IOEvent} to set
580 |  |
          */
581 |  |
         protected void setIOEvent(IOEvent<Context> ioEvent){
582 | 58626 |
             this.ioEvent = ioEvent;
583 | 58626 |
         }
584 |  |
585 |  |
         /**
586 |  |
          * Return the current {@link IOEvent} associated with this
587 |  |
          * instance.
588 |  |
          * @return IOEvent the current {@link IOEvent} associated with this
589 |  |
          * instance.
590 |  |
          */
591 |  |
         protected IOEvent getIOEvent(){
592 | 58626 |
             return ioEvent;
593 |  |
         }
594 |  |
595 |  |
596 |  |
         /**
597 |  |
          * Return the current {@link Controller#Protocol} this instance is executing.
598 |  |
          * @return the current Controller.Protocol this instance is executing.
599 |  |
          */
600 |  |
         public Controller.Protocol getProtocol() {
601 | 133799 |
             return selectorHandler.protocol();
602 |  |
         }
603 |  |
604 |  |
605 |  |
         /**
606 |  |
          * @Deprecated
607 |  |
          *
608 |  |
          * Set the current {@link Controller#Protocol} this instance is executing.
609 |  |
          * @param protocol The current protocol.
610 |  |
          */
611 |  |
         public void setProtocol(Controller.Protocol protocol) {
612 | 0 |
         }
613 |  |
614 |  |
615 |  |
         /**
616 |  |
          * Return the current {@link SelectorHandler} this instance is executing.
617 |  |
          * @return the current {@link SelectorHandler} this instance is executing.
618 |  |
          */
619 |  |
         public SelectorHandler getSelectorHandler() {
620 | 426589 |
             return selectorHandler;
621 |  |
         }
622 |  |
623 |  |
         /**
624 |  |
          * Set the current {@link SelectorHandler} this instance is executing.
625 |  |
          * @param selectorHandler {@link SelectorHandler}
626 |  |
          */
627 |  |
         public void setSelectorHandler(SelectorHandler selectorHandler) {
628 | 486285 |
             this.selectorHandler = selectorHandler;
629 | 486285 |
         }
630 |  |
631 |  |
632 |  |
         /**
633 |  |
          * Returns {@link AsyncQueueReadable}, assciated with the current
634 |  |
          * {@link Context}. This method is not threadsafe.
635 |  |
          *
636 |  |
          * @return {@link AsyncQueueReadable}
637 |  |
          */
638 |  |
         public AsyncQueueReadable getAsyncQueueReadable() {
639 | 0 |
             if (asyncQueueReadable == null) {
640 | 0 |
                 asyncQueueReadable = new AsyncQueueReadableContextWrapper();
641 |  |
             }
642 |  |
643 | 0 |
             return asyncQueueReadable;
644 |  |
         }
645 |  |
646 |  |
         /**
647 |  |
          * Returns {@link AsyncQueueWritable}, assciated with the current
648 |  |
          * {@link Context}. This method is not threadsafe.
649 |  |
          *
650 |  |
          * @return {@link AsyncQueueWritable}
651 |  |
          */
652 |  |
         public AsyncQueueWritable getAsyncQueueWritable() {
653 | 86662 |
             if (asyncQueueWritable == null) {
654 | 41 |
                 asyncQueueWritable = new AsyncQueueWritableContextWrapper();
655 |  |
             }
656 |  |
657 | 86662 |
             return asyncQueueWritable;
658 |  |
         }
659 |  |
660 |  |
         /**
661 |  |
          * Return the {@linkAsyncQueueReader}
662 |  |
          * @return the {@linkAsyncQueueReader}
663 |  |
          */
664 |  |
         protected AsyncQueueReader getAsyncQueueReader() {
665 | 0 |
             return asyncQueueReader;
666 |  |
         }
667 |  |
668 |  |
         /**
669 |  |
          * Set the {@linkAsyncQueueReader}
670 |  |
          * @param asyncQueueReader {@linkAsyncQueueReader}
671 |  |
          */
672 |  |
         protected void setAsyncQueueReader(AsyncQueueReader asyncQueueReader) {
673 | 161370 |
             this.asyncQueueReader = asyncQueueReader;
674 | 161370 |
         }
675 |  |
676 |  |
         /**
677 |  |
          * Return the {@linkAsyncQueueWriter}
678 |  |
          * @return the {@linkAsyncQueueWriter}
679 |  |
          */
680 |  |
         protected AsyncQueueWriter getAsyncQueueWriter() {
681 | 0 |
             return asyncQueueWriter;
682 |  |
         }
683 |  |
684 |  |
         /**
685 |  |
          * Set the {@linkAsyncQueueWriter}
686 |  |
          * @param asyncQueueWriter {@linkAsyncQueueWriter}
687 |  |
          */
688 |  |
         protected void setAsyncQueueWriter(AsyncQueueWriter asyncQueueWriter) {
689 | 161370 |
             this.asyncQueueWriter = asyncQueueWriter;
690 | 161370 |
         }
691 |  |
692 | 82 |
         private class AsyncQueueWritableContextWrapper implements AsyncQueueWritable {
693 |  |
             /**
694 |  |
             * {@inheritDoc}
695 |  |
             */
696 |  |
             public void writeToAsyncQueue(ByteBuffer buffer) throws IOException {
697 | 0 |
                 asyncQueueWriter.write(key, buffer);
698 | 0 |
             }
699 |  |
700 |  |
             /**
701 |  |
              * {@inheritDoc}
702 |  |
              */
703 |  |
             public void writeToAsyncQueue(ByteBuffer buffer,
704 |  |
                     AsyncWriteCallbackHandler callbackHandler) throws IOException {
705 | 0 |
                 asyncQueueWriter.write(key, buffer, callbackHandler);
706 | 0 |
             }
707 |  |
708 |  |
             /**
709 |  |
              * {@inheritDoc}
710 |  |
              */
711 |  |
             public void writeToAsyncQueue(ByteBuffer buffer,
712 |  |
                     AsyncWriteCallbackHandler callbackHandler,
713 |  |
                     AsyncQueueDataProcessor writePreProcessor) throws IOException {
714 | 0 |
                 asyncQueueWriter.write(key, buffer, callbackHandler, writePreProcessor);
715 | 0 |
             }
716 |  |
717 |  |
             /**
718 |  |
              * {@inheritDoc}
719 |  |
              */
720 |  |
             public void writeToAsyncQueue(ByteBuffer buffer,
721 |  |
                     AsyncWriteCallbackHandler callbackHandler,
722 |  |
                     AsyncQueueDataProcessor writePreProcessor,
723 |  |
                     boolean isCloneByteBuffer) throws IOException {
724 | 66662 |
                 asyncQueueWriter.write(key, buffer, callbackHandler,
725 |  |
                         writePreProcessor, isCloneByteBuffer);
726 | 66662 |
             }
727 |  |
728 |  |
             /**
729 |  |
             * {@inheritDoc}
730 |  |
             */
731 |  |
             public void writeToAsyncQueue(SocketAddress dstAddress, ByteBuffer buffer)
732 |  |
                     throws IOException {
733 | 0 |
                 asyncQueueWriter.write(key, dstAddress, buffer);
734 | 0 |
             }
735 |  |
736 |  |
             /**
737 |  |
             * {@inheritDoc}
738 |  |
             */
739 |  |
             public void writeToAsyncQueue(SocketAddress dstAddress, ByteBuffer buffer,
740 |  |
                     AsyncWriteCallbackHandler callbackHandler) throws IOException {
741 | 0 |
                 asyncQueueWriter.write(key, dstAddress, buffer,
742 |  |
                         callbackHandler);
743 | 0 |
             }
744 |  |
745 |  |
             /**
746 |  |
             * {@inheritDoc}
747 |  |
             */
748 |  |
             public void writeToAsyncQueue(SocketAddress dstAddress, ByteBuffer buffer,
749 |  |
                     AsyncWriteCallbackHandler callbackHandler,
750 |  |
                     AsyncQueueDataProcessor writePreProcessor) throws IOException {
751 | 0 |
                 asyncQueueWriter.write(key, dstAddress, buffer,
752 |  |
                         callbackHandler, writePreProcessor);
753 | 0 |
             }
754 |  |
755 |  |
             /**
756 |  |
             * {@inheritDoc}
757 |  |
             */
758 |  |
             public void writeToAsyncQueue(SocketAddress dstAddress, ByteBuffer buffer,
759 |  |
                     AsyncWriteCallbackHandler callbackHandler,
760 |  |
                     AsyncQueueDataProcessor writePreProcessor, boolean isCloneByteBuffer)
761 |  |
                     throws IOException {
762 | 20000 |
                 asyncQueueWriter.write(key, dstAddress, buffer,
763 |  |
                         callbackHandler, writePreProcessor, isCloneByteBuffer);
764 | 20000 |
             }
765 |  |
         }
766 |  |
767 | 0 |
         private class AsyncQueueReadableContextWrapper implements AsyncQueueReadable {
768 |  |
             /**
769 |  |
             * {@inheritDoc}
770 |  |
             */
771 |  |
             public void readFromAsyncQueue(ByteBuffer buffer,
772 |  |
                     AsyncReadCallbackHandler callbackHandler) throws IOException {
773 | 0 |
                 asyncQueueReader.read(key, buffer, callbackHandler);
774 | 0 |
             }
775 |  |
776 |  |
             /**
777 |  |
             * {@inheritDoc}
778 |  |
             */
779 |  |
             public void readFromAsyncQueue(ByteBuffer buffer,
780 |  |
                     AsyncReadCallbackHandler callbackHandler,
781 |  |
                     AsyncReadCondition condition) throws IOException {
782 | 0 |
                 asyncQueueReader.read(key, buffer, callbackHandler, condition);
783 | 0 |
             }
784 |  |
785 |  |
             /**
786 |  |
             * {@inheritDoc}
787 |  |
             */
788 |  |
             public void readFromAsyncQueue(ByteBuffer buffer,
789 |  |
                     AsyncReadCallbackHandler callbackHandler,
790 |  |
                     AsyncReadCondition condition,
791 |  |
                     AsyncQueueDataProcessor readPostProcessor) throws IOException {
792 | 0 |
                 asyncQueueReader.read(key, buffer, callbackHandler,
793 |  |
                         condition, readPostProcessor);
794 | 0 |
             }
795 |  |
         }
796 |  |
797 |  |
798 |  |
         /**
799 |  |
          * Suspend the execution of this {@link Context}. Suspending the execution
800 |  |
          * allow application to store the current instance, and re-use it later
801 |  |
          * by not only the  Thread used when called suspend, but also from any other Thread.
802 |  |
          * A suspended Context will not be re-used by any other transaction and Thread.
803 |  |
          * A suspended Context will keep its current state intact, meaning its
804 |  |
          * SelectionKey, attributes, SelectorHandler, etc, will not change. Internally,
805 |  |
          * The Context will not be recyled and will not be re-used by any Thread.
806 |  |
          *
807 |  |
          * When invoked this method will automatically set the
808 |  |
          * {@link Context#setKeyRegistrationState} to {@link KeyRegistrationState}
809 |  |
          * to KeyRegistrationState.NONE.
810 |  |
          *
811 |  |
          * Invoking this method many times as not effect once suspended.
812 |  |
          */
813 |  |
         public void suspend(){
814 | 0 |
             if (isSuspended) return;
815 | 0 |
             isSuspended = true;
816 | 0 |
             incrementRefCount();
817 | 0 |
             setKeyRegistrationState(keyRegistrationState.NONE);
818 | 0 |
         }
819 |  |
820 |  |
821 |  |
         /**
822 |  |
          * Return <tt>true</tt> if this Context has been suspended by
823 |  |
          * invoking {@link suspend}. When suspended, invoking {@link Context#recycle}
824 |  |
          * will throw an {@link IllegalStateException}
825 |  |
          * @return <tt>true</tt> if this Context has been suspended
826 |  |
          */
827 |  |
         public boolean isSuspended(){
828 | 0 |
             return isSuspended;
829 |  |
         }
830 |  |
831 |  |
832 |  |
         /**
833 |  |
          * Resume a {@link #suspend}ed {@link Context}.
834 |  |
          *  <strong>Resume will not call {@link Context#recycle}</strong>. So
835 |  |
          * after the caller is finished using Context caller must
836 |  |
          * call {@link  Controller#returnContext(com.sun.grizzly.Context)}
837 |  |
          * to  mark it as a candidate  for being re-used by another Thread and connection.
838 |  |
          *
839 |  |
          * <strong>Important. When resumed, all operations done on this
840 |  |
          * object are not thread-safe and there is probability that another
841 |  |
          * thread is already using this object. Never use this object once resumed.</strong>
842 |  |
          *
843 |  |
          * When invoked this method will automatically set the
844 |  |
          * {@link Context#setKeyRegistrationState} to {@link KeyRegistrationState}
845 |  |
          * to KeyRegistrationState.REGISTER and automatically re-enable read and
846 |  |
          * write operations.
847 |  |
          *
848 |  |
          * If the Context hasn't been suspended, calling that method has no effet.
849 |  |
          */
850 |  |
         public void resume(){
851 | 0 |
             if (!isSuspended) return;
852 | 0 |
             isSuspended = false;
853 | 0 |
             selectorHandler.register(key, SelectionKey.OP_READ);
854 | 0 |
         }
855 |  |
856 |  |
857 |  |
         /**
858 |  |
          * Cancel a {@link #suspend}ed {@link Context}. Invoking this method will
859 |  |
          * automatically clean the state of this Context and mark it as a candidate
860 |  |
          * for being re-used by another Thread and connection.
861 |  |
          *
862 |  |
          * <strong>Important. When cancelled, all operations done on this
863 |  |
          * object are not thread-safe and there is probability that another
864 |  |
          * thread is already using this object. Never use this object once cancelled.</strong>
865 |  |
          *
866 |  |
          *
867 |  |
          * When invoked this method will automatically close the underlying
868 |  |
          * connection (represented by its {@link SelectionKey}.
869 |  |
          *
870 |  |
          * If the Context hasn't been suspended, calling that method has no effet.
871 |  |
          */
872 |  |
         public void cancel(){
873 | 0 |
             if (!isSuspended) return;
874 | 0 |
             isSuspended = false;
875 | 0 |
             selectorHandler.getSelectionKeyHandler().cancel(key);
876 | 0 |
             getController().returnContext(this);
877 | 0 |
         }
878 |  |
         /**
879 |  |
          * Called by outer Threads that are not instances of {@link WorkerThread} to
880 |  |
          * indicate that this {@link Context} should not be
881 |  |
          * {@link #recycle()} or offered back to its pool.
882 |  |
          *
883 |  |
          * When a outer Thread is done with {@link Context} it must call
884 |  |
          * {@link Controller#returnContext(com.sun.grizzly.Context) to
885 |  |
          * ensure that {@link Context} will be properly recycled.
886 |  |
          *
887 |  |
          * @return Current Thread reference count
888 |  |
          */
889 |  |
         public void incrementRefCount(){
890 | 0 |
              refCounter.incrementAndGet();
891 | 0 |
         }
892 |  |
893 |  |
         /**
894 |  |
          * Decrements the reference count of this {@link Context}.
895 |  |
          * Threads wanting to release {@link Context} should not call
896 |  |
          * this method but instead use
897 |  |
          * {@link Controller#returnContext(com.sun.grizzly.Context)}
898 |  |
          * @return return decremented reference count
899 |  |
          */
900 |  |
         public int  decrementRefCount(){
901 | 161370 |
             return  refCounter.decrementAndGet();
902 |  |
     }
903 |  |
904 |  |
     }