Skip to content

Commit e100e25

Browse files
authored
Use a non-blocking output stream for socket writes (docker-java#1769)
Essentially: Channels.newOutputStream and Channels.newInputStream are synchronizing on the blocking lock provided by the SelectableChannel#blockingLock method. This prevents writing a command to a container stdin while there is no output printed to stdout. This is a long known issue in java and was fixed partially in java 13 (see https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8222774). Concurrent read/writes aren't a problem there anymore as well. References: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4509080 https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4774871 https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6977788 Closes docker-java#1768
1 parent 078348f commit e100e25

1 file changed

Lines changed: 21 additions & 1 deletion

File tree

  • docker-java-transport/src/main/java/com/github/dockerjava/transport

docker-java-transport/src/main/java/com/github/dockerjava/transport/UnixSocket.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
import java.net.Socket;
77
import java.net.SocketAddress;
88
import java.net.SocketException;
9+
import java.nio.ByteBuffer;
910
import java.nio.channels.Channels;
1011
import java.nio.channels.SocketChannel;
12+
import java.nio.channels.WritableByteChannel;
1113

1214
public class UnixSocket extends AbstractSocket {
1315

@@ -67,7 +69,7 @@ public OutputStream getOutputStream() throws IOException {
6769
throw new SocketException("Socket output is shutdown");
6870
}
6971

70-
return Channels.newOutputStream(socketChannel);
72+
return Channels.newOutputStream(new WrappedWritableByteChannel());
7173
}
7274

7375
@Override
@@ -85,4 +87,22 @@ public void close() throws IOException {
8587
super.close();
8688
this.socketChannel.close();
8789
}
90+
91+
private class WrappedWritableByteChannel implements WritableByteChannel {
92+
93+
@Override
94+
public int write(ByteBuffer src) throws IOException {
95+
return UnixSocket.this.socketChannel.write(src);
96+
}
97+
98+
@Override
99+
public boolean isOpen() {
100+
return UnixSocket.this.socketChannel.isOpen();
101+
}
102+
103+
@Override
104+
public void close() throws IOException {
105+
UnixSocket.this.socketChannel.close();
106+
}
107+
}
88108
}

0 commit comments

Comments
 (0)