Coverage Report - com.sun.grizzly.util.SelectorFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
SelectorFactory
49 %
37/75
36 %
10/28
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  
 package com.sun.grizzly.util;
 39  
 
 40  
 import com.sun.grizzly.Controller;
 41  
 import java.io.IOException;
 42  
 import java.nio.channels.Selector;
 43  
 import java.util.EmptyStackException;
 44  
 import java.util.Stack;
 45  
 import java.util.logging.Level;
 46  
 import java.util.logging.Logger;
 47  
 
 48  
 /**
 49  
  * Factory used to dispatch/share {@link Selector}.
 50  
  *
 51  
  * @author Scott Oaks
 52  
  * @author Jean-Francois Arcand
 53  
  */
 54  0
 public class SelectorFactory{
 55  
     
 56  
     public static final int DEFAULT_MAX_SELECTORS = 20;
 57  
     
 58  
     /**
 59  
      * The timeout before we exit.
 60  
      */
 61  1
     public static long timeout = 5000;
 62  
     
 63  
     
 64  
     /**
 65  
      * The number of {@link Selector} to create.
 66  
      */
 67  1
     private static int maxSelectors = DEFAULT_MAX_SELECTORS;
 68  
     
 69  
     
 70  
     /**
 71  
      * Cache of {@link Selector}
 72  
      */
 73  1
     private final static Stack<Selector> selectors = new Stack<Selector>();
 74  
     
 75  
     
 76  
     /**
 77  
      * have we created the Selector instances.
 78  
      */
 79  1
     private static boolean initialized = false;
 80  
     
 81  
     /**
 82  
      * Set max selector pool size.
 83  
      * @param size max pool size
 84  
      */
 85  
     public final static void setMaxSelectors(int size) throws IOException {
 86  1
         synchronized(selectors) {
 87  1
             if (size > maxSelectors || !initialized) {
 88  
                 // if not initialized yet - grow cache by size
 89  1
                 if (!initialized) maxSelectors = 0;
 90  
                 
 91  1
                 grow(size);
 92  0
             }  else if (size < maxSelectors) {
 93  0
                 reduce(size);
 94  
             }
 95  
             
 96  1
             maxSelectors = size;
 97  1
             initialized = true;
 98  1
         }
 99  1
     }
 100  
     
 101  
     /**
 102  
      * Returns max selector pool size
 103  
      * @return max pool size
 104  
      */
 105  
     public final static int getMaxSelectors() {
 106  0
         return maxSelectors;
 107  
     }
 108  
     
 109  
     /**
 110  
      * Get a exclusive {@link Selector}
 111  
      * @return {@link Selector}
 112  
      */
 113  
     public final static Selector getSelector() {
 114  759
         synchronized(selectors) {
 115  759
             if (!initialized) {
 116  
                 try {
 117  1
                     setMaxSelectors(maxSelectors);
 118  0
                 } catch (IOException e) {
 119  0
                     Logger logger = Controller.logger();
 120  0
                     if (logger.isLoggable(Level.WARNING)) {
 121  0
                         logger.log(Level.WARNING, "SelectorFactory lazy initialization", e);
 122  
                     }
 123  1
                 }
 124  
             }
 125  
             
 126  759
             Selector s = null;
 127  
             try {
 128  759
                 if ( selectors.size() != 0 )
 129  759
                     s = selectors.pop();
 130  759
             } catch (EmptyStackException ex){}
 131  
                        
 132  759
             int attempts = 0;
 133  
             try{
 134  759
                 while (s == null && attempts < 2) {
 135  0
                     selectors.wait(timeout);
 136  
                     try {
 137  0
                         if ( selectors.size() != 0 )
 138  0
                             s = selectors.pop();
 139  0
                     } catch (EmptyStackException ex){
 140  0
                         break;
 141  0
                     }
 142  0
                     attempts++;
 143  
                 }
 144  759
             } catch (InterruptedException ex){}
 145  759
             return s;
 146  0
         }
 147  
     }
 148  
 
 149  
 
 150  
     /**
 151  
      * Return the {@link Selector} to the cache
 152  
      * @param s {@link Selector}
 153  
      */
 154  
     public final static void returnSelector(Selector s) {
 155  759
         synchronized(selectors) {
 156  759
             selectors.push(s);
 157  759
             if (selectors.size() == 1)
 158  0
                 selectors.notify();
 159  759
         }
 160  759
     }
 161  
 
 162  
     /**
 163  
      * Executes <code>Selector.selectNow()</code> and returns 
 164  
      * the {@link Selector} to the cache
 165  
      */
 166  
     public final static void selectNowAndReturnSelector(Selector s) {
 167  
         try {
 168  759
             s.selectNow();
 169  759
             returnSelector(s);
 170  0
         } catch(IOException e) {
 171  0
             Logger logger = Controller.logger();
 172  0
             logger.log(Level.WARNING, 
 173  
                     "Unexpected problem when releasing temporary Selector", e);
 174  
             try {
 175  0
                 s.close();
 176  0
             } catch(IOException ee) {
 177  
                 // We are not interested
 178  0
             }
 179  
             
 180  
             try {
 181  0
                 reimburseSelector();
 182  0
             } catch(IOException ee) {
 183  0
                 logger.log(Level.WARNING,
 184  
                         "Problematic Selector could not be reimbursed!", ee);
 185  0
             }
 186  759
         }
 187  759
     }
 188  
 
 189  
     /**
 190  
      * Add Selector to the cache.
 191  
      * This method could be called to reimberse a lost or problematic Selector.
 192  
      * 
 193  
      * @throws java.io.IOException
 194  
      */
 195  
     public final static void reimburseSelector() throws IOException {
 196  0
         returnSelector(createSelector());
 197  0
     }
 198  
 
 199  
     /**
 200  
      * Creeate Selector
 201  
      * @return Selector
 202  
      * @throws java.io.IOException
 203  
      */
 204  
     protected static Selector createSelector() throws IOException {
 205  20
         return Selector.open();
 206  
     }
 207  
     
 208  
     
 209  
     /**
 210  
      * Increase {@link Selector} pool size
 211  
      */
 212  
     private static void grow(int size) throws IOException {
 213  21
         for(int i=0; i<size - maxSelectors; i++) {
 214  20
             selectors.add(createSelector());
 215  
         }
 216  1
     }
 217  
 
 218  
     /**
 219  
      * Decrease {@link Selector} pool size
 220  
      */
 221  
     private static void reduce(int size) {
 222  0
         for(int i=0; i<maxSelectors - size; i++) {
 223  
             try {
 224  0
                 Selector selector = selectors.pop();
 225  0
                 selector.close();
 226  0
             } catch(IOException e) {
 227  0
                 Logger logger = Controller.logger();
 228  0
                 if (logger.isLoggable(Level.FINE)) {
 229  0
                     logger.log(Level.FINE, "SelectorFactory.reduce", e);
 230  
                 }
 231  0
             }
 232  
         }
 233  0
     }
 234  
 
 235  
 }