Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjfrijters <jfrijters>2007-09-17 09:09:50 +0400
committerjfrijters <jfrijters>2007-09-17 09:09:50 +0400
commit79ae150bca98796b3948b392d74e55500686751e (patch)
treed8f0dd01d38802674edabf109b59805f85261d24 /openjdk/sun/nio/ch
parent2da6e524b5a560e478a8cf42614d7e108ab3b6c9 (diff)
Use Pipe instead of socket closing to trigger wakeup to avoid race condition between Socket.Close/Socket.Select.
Diffstat (limited to 'openjdk/sun/nio/ch')
-rw-r--r--openjdk/sun/nio/ch/DotNetSelectorImpl.java43
1 files changed, 33 insertions, 10 deletions
diff --git a/openjdk/sun/nio/ch/DotNetSelectorImpl.java b/openjdk/sun/nio/ch/DotNetSelectorImpl.java
index 47ae5d3d..ea876e0a 100644
--- a/openjdk/sun/nio/ch/DotNetSelectorImpl.java
+++ b/openjdk/sun/nio/ch/DotNetSelectorImpl.java
@@ -36,6 +36,7 @@ import cli.System.Net.Sockets.SelectMode;
import cli.System.Collections.ArrayList;
import java.io.IOException;
import java.nio.channels.ClosedSelectorException;
+import java.nio.channels.Pipe;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
@@ -51,10 +52,15 @@ import java.util.Set;
final class DotNetSelectorImpl extends SelectorImpl
{
- private Socket wakeupSourceFd;
private ArrayList channelArray = new ArrayList();
private long updateCount = 0;
+ //Pipe used as a wakeup object.
+ private final Pipe wakeupPipe;
+
+ // File descriptors corresponding to source and sink
+ private final Socket wakeupSourceFd, wakeupSinkFd;
+
// Lock for interrupt triggering and clearing
private final Object interruptLock = new Object();
private volatile boolean interruptTriggered = false;
@@ -72,10 +78,16 @@ final class DotNetSelectorImpl extends SelectorImpl
}
private final HashMap<Socket, MapEntry> fdMap = new HashMap<Socket, MapEntry>();
- DotNetSelectorImpl(SelectorProvider sp)
+ DotNetSelectorImpl(SelectorProvider sp) throws IOException
{
super(sp);
- createWakeupSocket();
+ wakeupPipe = Pipe.open();
+ wakeupSourceFd = ((SelChImpl)wakeupPipe.source()).getFD().getSocket();
+
+ // Disable the Nagle algorithm so that the wakeup is more immediate
+ SinkChannelImpl sink = (SinkChannelImpl)wakeupPipe.sink();
+ (sink.sc).socket().setTcpNoDelay(true);
+ wakeupSinkFd = ((SelChImpl)sink).getFD().getSocket();
}
protected int doSelect(long timeout) throws IOException
@@ -234,7 +246,11 @@ final class DotNetSelectorImpl extends SelectorImpl
if (channelArray != null)
{
// prevent further wakeup
- wakeup();
+ synchronized (interruptLock) {
+ interruptTriggered = true;
+ }
+ wakeupPipe.sink().close();
+ wakeupPipe.source().close();
for (int i = 0; i < channelArray.get_Count(); i++)
{ // Deregister channels
SelectionKeyImpl ski = (SelectionKeyImpl)channelArray.get_Item(i);
@@ -275,27 +291,34 @@ final class DotNetSelectorImpl extends SelectorImpl
{
if (!interruptTriggered)
{
- wakeupSourceFd.Close();
+ setWakeupSocket();
interruptTriggered = true;
}
}
return this;
}
+ // Sets Windows wakeup socket to a signaled state.
+ private void setWakeupSocket() {
+ wakeupSinkFd.Send(new byte[1]);
+ }
+
// Sets Windows wakeup socket to a non-signaled state.
- private void resetWakeupSocket()
- {
+ private void resetWakeupSocket() {
synchronized (interruptLock)
{
if (interruptTriggered == false)
return;
- createWakeupSocket();
+ resetWakeupSocket0(wakeupSourceFd);
interruptTriggered = false;
}
}
- private void createWakeupSocket()
+ private static void resetWakeupSocket0(Socket wakeupSourceFd)
{
- wakeupSourceFd = new Socket(AddressFamily.wrap(AddressFamily.InterNetwork), SocketType.wrap(SocketType.Dgram), ProtocolType.wrap(ProtocolType.Udp));
+ while (wakeupSourceFd.get_Available() > 0)
+ {
+ wakeupSourceFd.Receive(new byte[1]);
+ }
}
}