Throw an RejectedExecutionException if someone tries to register a Channel to an AbstractNioWorker that was shutdown before. Part of #582

This commit is contained in:
norman 2012-09-04 07:40:07 +02:00
parent 3bdccc633a
commit 3d441821a9
4 changed files with 117 additions and 10 deletions

View File

@ -35,6 +35,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReadWriteLock;
@ -128,22 +129,18 @@ abstract class AbstractNioWorker implements Worker {
void register(AbstractNioChannel<?> channel, ChannelFuture future) {
Runnable registerTask = createRegisterTask(channel, future);
synchronized (startStopLock) {
if (selector == null) {
// the selector was null this means the Worker has already been shutdown.
throw new RejectedExecutionException("Worker has already been shutdown");
}
Runnable registerTask = createRegisterTask(channel, future);
boolean offered = registerTaskQueue.offer(registerTask);
assert offered;
if (wakenUp.compareAndSet(false, true)) {
// wake up the selector to speed things
selector = this.selector;
// Check if the selector is not null to prevent NPE if selector was
// set to null from another thread. See #469
if (selector != null) {
selector.wakeup();
}
selector.wakeup();
}
}

View File

@ -0,0 +1,60 @@
/*
* 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 static org.easymock.EasyMock.*;
import static junit.framework.Assert.*;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import org.jboss.netty.channel.ChannelFuture;
import org.junit.Test;
public abstract class AbstractNioWorkerTest {
@Test
public void testShutdownWorkerThrowsException() throws InterruptedException {
AbstractNioChannel<?> mockChannel = createMock(AbstractNioChannel.class);
replay(mockChannel);
ChannelFuture mockFuture = createMock(ChannelFuture.class);
replay(mockFuture);
ExecutorService executor = Executors.newCachedThreadPool();
AbstractNioWorker worker = createWorker(executor);
executor.shutdownNow();
// give the Selector time to detect the shutdown
Thread.sleep(SelectorUtil.DEFAULT_SELECT_TIMEOUT * 10);
try {
worker.register(mockChannel, mockFuture);
fail();
} catch (RejectedExecutionException e) {
// expected
}
verify(mockChannel, mockFuture);
reset(mockChannel, mockFuture);
}
protected abstract AbstractNioWorker createWorker(Executor executor);
}

View File

@ -0,0 +1,25 @@
/*
* 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 java.util.concurrent.Executor;
public class NioDatagramWorkerTest extends AbstractNioWorkerTest {
protected AbstractNioWorker createWorker(Executor executor) {
return new NioDatagramWorker(executor);
}
}

View File

@ -0,0 +1,25 @@
/*
* 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 java.util.concurrent.Executor;
public class NioWorkerTest extends AbstractNioWorkerTest {
protected AbstractNioWorker createWorker(Executor executor) {
return new NioWorker(executor);
}
}