org.jboss.netty.channel.socket.nio.AbstractNioBossPool Maven / Gradle / Ivy
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package org.jboss.netty.channel.socket.nio;
import org.jboss.netty.logging.InternalLogger;
import org.jboss.netty.logging.InternalLoggerFactory;
import org.jboss.netty.util.ExternalResourceReleasable;
import org.jboss.netty.util.internal.ExecutorUtil;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public abstract class AbstractNioBossPool
implements BossPool, ExternalResourceReleasable {
/**
* The boss pool raises an exception unless all boss threads start and run within this timeout (in seconds.)
*/
private static final int INITIALIZATION_TIMEOUT = 10;
private static final InternalLogger logger = InternalLoggerFactory.getInstance(AbstractNioBossPool.class);
private final Boss[] bosses;
private final AtomicInteger bossIndex = new AtomicInteger();
private final Executor bossExecutor;
private final AtomicBoolean initialized = new AtomicBoolean(false);
/**
* Create a new instance
*
* @param bossExecutor the {@link Executor} to use for the {@link Boss}'s
* @param bossCount the count of {@link Boss}'s to create
*/
AbstractNioBossPool(Executor bossExecutor, int bossCount) {
this(bossExecutor, bossCount, true);
}
AbstractNioBossPool(Executor bossExecutor, int bossCount, boolean autoInit) {
if (bossExecutor == null) {
throw new NullPointerException("bossExecutor");
}
if (bossCount <= 0) {
throw new IllegalArgumentException(
"bossCount (" + bossCount + ") " +
"must be a positive integer.");
}
bosses = new Boss[bossCount];
this.bossExecutor = bossExecutor;
if (autoInit) {
init();
}
}
protected void init() {
if (!initialized.compareAndSet(false, true)) {
throw new IllegalStateException("initialized already");
}
for (int i = 0; i < bosses.length; i++) {
bosses[i] = newBoss(bossExecutor);
}
waitForBossThreads();
}
private void waitForBossThreads() {
long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(INITIALIZATION_TIMEOUT);
boolean warn = false;
for (Boss boss: bosses) {
if (!(boss instanceof AbstractNioSelector)) {
continue;
}
AbstractNioSelector selector = (AbstractNioSelector) boss;
long waitTime = deadline - System.nanoTime();
try {
if (waitTime <= 0) {
if (selector.thread == null) {
warn = true;
break;
}
} else if (!selector.startupLatch.await(waitTime, TimeUnit.NANOSECONDS)) {
warn = true;
break;
}
} catch (InterruptedException ignore) {
// Stop waiting for the boss threads and let someone else take care of the interruption.
Thread.currentThread().interrupt();
break;
}
}
if (warn) {
logger.warn(
"Failed to get all boss threads ready within " + INITIALIZATION_TIMEOUT + " second(s). " +
"Make sure to specify the executor which has more threads than the requested bossCount. " +
"If unsure, use Executors.newCachedThreadPool().");
}
}
/**
* Create a new {@link Boss} which uses the given {@link Executor} to service IO
*
*
* @param executor the {@link Executor} to use
* @return worker the new {@link Boss}
*/
protected abstract E newBoss(Executor executor);
@SuppressWarnings("unchecked")
public E nextBoss() {
return (E) bosses[Math.abs(bossIndex.getAndIncrement() % bosses.length)];
}
public void rebuildSelectors() {
for (Boss boss: bosses) {
boss.rebuildSelector();
}
}
public void releaseExternalResources() {
shutdown();
ExecutorUtil.shutdownNow(bossExecutor);
}
public void shutdown() {
for (Boss boss: bosses) {
boss.shutdown();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy