提交 b905eaa5 编写于 作者: A alanb

6823609: (se) Selector.select hangs on Windows under load

Reviewed-by: sherman
上级 181c000b
......@@ -34,7 +34,6 @@ import java.nio.channels.Selector;
import java.nio.channels.ClosedSelectorException;
import java.nio.channels.Pipe;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
......@@ -72,7 +71,7 @@ final class WindowsSelectorImpl extends SelectorImpl {
private int threadsCount = 0;
// A list of helper threads for select.
private final List<Thread> threads = new ArrayList<Thread>();
private final List<SelectThread> threads = new ArrayList<SelectThread>();
//Pipe used as a wakeup object.
private final Pipe wakeupPipe;
......@@ -201,7 +200,7 @@ final class WindowsSelectorImpl extends SelectorImpl {
Thread.currentThread().interrupt();
}
}
if (thread.index >= threads.size()) { // redundant thread
if (thread.isZombie()) { // redundant thread
return true; // will cause run() to exit.
} else {
thread.lastRun = runsCounter; // update lastRun
......@@ -388,9 +387,10 @@ final class WindowsSelectorImpl extends SelectorImpl {
// Represents a helper thread used for select.
private final class SelectThread extends Thread {
private int index; // index of this thread
SubSelector subSelector;
private final int index; // index of this thread
final SubSelector subSelector;
private long lastRun = 0; // last run number
private volatile boolean zombie;
// Creates a new thread
private SelectThread(int i) {
this.index = i;
......@@ -398,6 +398,12 @@ final class WindowsSelectorImpl extends SelectorImpl {
//make sure we wait for next round of poll
this.lastRun = startLock.runsCounter;
}
void makeZombie() {
zombie = true;
}
boolean isZombie() {
return zombie;
}
public void run() {
while (true) { // poll loop
// wait for the start of poll. If this thread has become
......@@ -432,7 +438,7 @@ final class WindowsSelectorImpl extends SelectorImpl {
} else if (threadsCount < threads.size()) {
// Some threads become redundant. Remove them from the threads List.
for (int i = threads.size() - 1 ; i >= threadsCount; i--)
threads.remove(i);
threads.remove(i).makeZombie();
}
}
......@@ -468,10 +474,9 @@ final class WindowsSelectorImpl extends SelectorImpl {
updateCount++;
int numKeysUpdated = 0;
numKeysUpdated += subSelector.processSelectedKeys(updateCount);
Iterator it = threads.iterator();
while (it.hasNext())
numKeysUpdated += ((SelectThread)it.next()).subSelector.
processSelectedKeys(updateCount);
for (SelectThread t: threads) {
numKeysUpdated += t.subSelector.processSelectedKeys(updateCount);
}
return numKeysUpdated;
}
......@@ -495,13 +500,13 @@ final class WindowsSelectorImpl extends SelectorImpl {
}
pollWrapper.free();
pollWrapper = null;
selectedKeys = null;
channelArray = null;
threads.clear();
// Call startThreads. All remaining helper threads now exit,
// since threads.size() = 0;
startLock.startThreads();
}
selectedKeys = null;
channelArray = null;
// Make all remaining helper threads exit
for (SelectThread t: threads)
t.makeZombie();
startLock.startThreads();
}
}
}
}
......
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6823609
* @summary Selector.select can hangs on Windows for cases where a helper thread
* becomes redudant but a new helper is immediately needed.
*/
import java.nio.channels.*;
import java.io.IOException;
public class HelperSlowToDie {
private static final int CHANNELS_PER_THREAD = 1023;
private static volatile boolean done;
public static void main(String[] args) throws IOException {
Selector sel = Selector.open();
// register channels
SocketChannel[] channels = new SocketChannel[CHANNELS_PER_THREAD];
for (int i=0; i<CHANNELS_PER_THREAD; i++) {
SocketChannel sc = SocketChannel.open();
sc.configureBlocking(false);
sc.register(sel, SelectionKey.OP_CONNECT);
channels[i] = sc;
}
sel.selectNow();
// Start threads to swamp all cores but one. This improves the chances
// of duplicating the bug.
Runnable busy = new Runnable() {
public void run() {
while (!done) ; // no nothing
}
};
int ncores = Runtime.getRuntime().availableProcessors();
for (int i=0; i<ncores-1; i++)
new Thread(busy).start();
// Loop changing the number of channels from 1023 to 1024 and back.
for (int i=0; i<1000; i++) {
SocketChannel sc = SocketChannel.open();
sc.configureBlocking(false);
sc.register(sel, SelectionKey.OP_CONNECT);
sel.selectNow(); // cause helper to spin up
sc.close();
sel.selectNow(); // cause helper to retire
}
// terminate busy threads
done = true;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册