33
33
import java .net .InetSocketAddress ;
34
34
import java .net .SocketAddress ;
35
35
import java .net .StandardSocketOptions ;
36
+ import java .net .UnixDomainSocketAddress ;
36
37
import java .nio .*;
37
38
import java .nio .channels .*;
38
39
import java .nio .file .Files ;
44
45
import java .security .SecureRandom ;
45
46
import java .util .Random ;
46
47
48
+ import static java .net .StandardProtocolFamily .UNIX ;
47
49
48
50
/**
49
51
* A simple Pipe implementation based on a socket connection.
@@ -67,12 +69,14 @@ private static class Initializer
67
69
{
68
70
69
71
private final SelectorProvider sp ;
72
+ private final boolean preferUnixDomain ;
70
73
private IOException ioe ;
71
74
SourceChannelImpl source ;
72
75
SinkChannelImpl sink ;
73
76
74
- private Initializer (SelectorProvider sp ) {
77
+ private Initializer (SelectorProvider sp , boolean preferUnixDomain ) {
75
78
this .sp = sp ;
79
+ this .preferUnixDomain = preferUnixDomain ;
76
80
}
77
81
78
82
@ Override
@@ -120,7 +124,7 @@ public void run() {
120
124
// Bind ServerSocketChannel to a port on the loopback
121
125
// address
122
126
if (ssc == null || !ssc .isOpen ()) {
123
- ssc = createListener ();
127
+ ssc = createListener (preferUnixDomain );
124
128
sa = ssc .getLocalAddress ();
125
129
}
126
130
@@ -162,28 +166,34 @@ public void run() {
162
166
try {
163
167
if (ssc != null )
164
168
ssc .close ();
169
+ if (sa instanceof UnixDomainSocketAddress uaddr ) {
170
+ Files .deleteIfExists (uaddr .getPath ());
171
+ }
165
172
} catch (IOException e2 ) {}
166
173
}
167
174
}
168
175
}
169
176
}
170
177
171
178
/**
172
- * Creates a Pipe implementation that supports buffering.
179
+ * Creates a (TCP) Pipe implementation that supports buffering.
173
180
*/
174
181
PipeImpl (SelectorProvider sp ) throws IOException {
175
- this (sp , true );
182
+ this (sp , true , false );
176
183
}
177
184
178
185
/**
179
- * Creates Pipe implementation that supports optionally buffering.
186
+ * Creates Pipe implementation that supports optionally buffering
187
+ * and is TCP by default, but if Unix domain is supported and
188
+ * preferAfUnix is true, then Unix domain sockets are used.
189
+ *
190
+ * @param preferAfUnix use Unix domain sockets if supported
180
191
*
181
- * @implNote Uses a loopback connection. When buffering is
182
- * disabled then it sets TCP_NODELAY on the sink channel.
192
+ * @param buffering if false set TCP_NODELAY on TCP sockets
183
193
*/
184
194
@ SuppressWarnings ("removal" )
185
- PipeImpl (SelectorProvider sp , boolean buffering ) throws IOException {
186
- Initializer initializer = new Initializer (sp );
195
+ PipeImpl (SelectorProvider sp , boolean preferAfUnix , boolean buffering ) throws IOException {
196
+ Initializer initializer = new Initializer (sp , preferAfUnix );
187
197
try {
188
198
AccessController .doPrivileged (initializer );
189
199
SinkChannelImpl sink = initializer .sink ;
@@ -205,8 +215,19 @@ public SinkChannelImpl sink() {
205
215
return sink ;
206
216
}
207
217
208
- private static ServerSocketChannel createListener () throws IOException {
209
- ServerSocketChannel listener = ServerSocketChannel .open ();
218
+ private static ServerSocketChannel createListener (boolean preferUnixDomain ) throws IOException {
219
+ ServerSocketChannel listener = null ;
220
+ if (preferUnixDomain && UnixDomainSockets .isSupported ()) {
221
+ try {
222
+ listener = ServerSocketChannel .open (UNIX );
223
+ listener .bind (null );
224
+ return listener ;
225
+ } catch (IOException | UnsupportedOperationException e ) {
226
+ if (listener != null )
227
+ listener .close ();
228
+ }
229
+ }
230
+ listener = ServerSocketChannel .open ();
210
231
InetAddress lb = InetAddress .getLoopbackAddress ();
211
232
listener .bind (new InetSocketAddress (lb , 0 ));
212
233
return listener ;
0 commit comments