View Javadoc

1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  
17  package org.jboss.netty.channel.socket.nio;
18  
19  import org.jboss.netty.channel.socket.Worker;
20  import org.jboss.netty.util.ExternalResourceReleasable;
21  import org.jboss.netty.util.internal.ExecutorUtil;
22  
23  import java.util.concurrent.Executor;
24  import java.util.concurrent.atomic.AtomicInteger;
25  
26  /**
27   * Abstract base class for {@link WorkerPool} implementations that create the {@link Worker}'s
28   * up-front and return them in a "fair" fashion when calling {@link #nextWorker()}
29   */
30  public abstract class AbstractNioWorkerPool<E extends AbstractNioWorker>
31          implements WorkerPool<E>, ExternalResourceReleasable {
32  
33      private final AbstractNioWorker[] workers;
34      private final AtomicInteger workerIndex = new AtomicInteger();
35      private final Executor workerExecutor;
36      private volatile boolean initDone;
37  
38      /**
39       * Create a new instance
40       *
41       * @param workerExecutor the {@link Executor} to use for the {@link Worker}'s
42       * @param workerCount the count of {@link Worker}'s to create
43       */
44      AbstractNioWorkerPool(Executor workerExecutor, int workerCount) {
45          this(workerExecutor, workerCount, true);
46      }
47  
48      AbstractNioWorkerPool(Executor workerExecutor, int workerCount, boolean autoInit) {
49          if (workerExecutor == null) {
50              throw new NullPointerException("workerExecutor");
51          }
52          if (workerCount <= 0) {
53              throw new IllegalArgumentException(
54                      "workerCount (" + workerCount + ") " + "must be a positive integer.");
55          }
56          workers = new AbstractNioWorker[workerCount];
57          this.workerExecutor = workerExecutor;
58          if (autoInit) {
59              init();
60          }
61      }
62      protected void init() {
63          if (initDone) {
64              throw new IllegalStateException("Init was done before");
65          }
66          initDone = true;
67  
68          for (int i = 0; i < workers.length; i++) {
69              workers[i] = newWorker(workerExecutor);
70          }
71      }
72  
73      /**
74       * Only here for backward compability and will be removed in later releases. Please use
75       * {@link #newWorker(Executor)}
76       *
77       *
78       * @param executor the {@link Executor} to use
79       * @return worker the new {@link Worker}
80       * @deprecated use {@link #newWorker(Executor)}
81       */
82      @Deprecated
83      protected E createWorker(Executor executor) {
84          throw new IllegalStateException("This will be removed. Override this and the newWorker(..) method!");
85      }
86  
87      /**
88       * Create a new {@link Worker} which uses the given {@link Executor} to service IO.
89       *
90       * This method will be made abstract in further releases (once {@link #createWorker(Executor)}
91       * was removed).
92       *
93       *
94       * @param executor the {@link Executor} to use
95       * @return worker the new {@link Worker}
96       */
97      @SuppressWarnings("deprecation")
98      protected E newWorker(Executor executor) {
99          return createWorker(executor);
100     }
101 
102     @SuppressWarnings("unchecked")
103     public E nextWorker() {
104         return (E) workers[Math.abs(workerIndex.getAndIncrement() % workers.length)];
105     }
106 
107     public void rebuildSelectors() {
108         for (AbstractNioWorker worker: workers) {
109             worker.rebuildSelector();
110         }
111     }
112 
113     public void releaseExternalResources() {
114         shutdown();
115         ExecutorUtil.shutdownNow(workerExecutor);
116     }
117 
118     public void shutdown() {
119         for (AbstractNioWorker worker: workers) {
120             worker.shutdown();
121         }
122     }
123 
124 }