@@ -121,6 +121,8 @@ final class ProcessIsolateThreadSupport {
121
121
private static final int INITIAL_REQUEST_CACHE_SIZE = 1 << 10 ;
122
122
private static final int MAX_REQUEST_CACHE_SIZE = 1 << 20 ;
123
123
124
+ private static final int MAX_INTERRUPTED_ATTACH_RETRIES = 10 ;
125
+
124
126
private final DispatchSupport dispatchSupport ;
125
127
private final ServerSocketChannel local ;
126
128
private UnixDomainSocketAddress peer ;
@@ -316,15 +318,29 @@ ThreadChannel attachThread() throws IOException {
316
318
* and {@code Context.interrupt()} interrupt threads.
317
319
*/
318
320
private SocketChannel connectPeer () throws IOException {
319
- while (true ) {
320
- SocketChannel c = SocketChannel .open (StandardProtocolFamily .UNIX );
321
- try {
322
- c .connect (peer );
323
- return c ;
324
- } catch (ClosedByInterruptException closed ) {
325
- // Retry on interrupt to avoid leaking cancellation semantics into
326
- // IsolateDeathHandler.
327
- // Closing or interrupting contexts may interrupt this thread.
321
+ int interruptCount = 0 ;
322
+ try {
323
+ while (true ) {
324
+ SocketChannel c = SocketChannel .open (StandardProtocolFamily .UNIX );
325
+ try {
326
+ c .connect (peer );
327
+ return c ;
328
+ } catch (ClosedByInterruptException closed ) {
329
+ if (interruptCount ++ < MAX_INTERRUPTED_ATTACH_RETRIES ) {
330
+ // Clear the thread interrupt status before retry
331
+ Thread .interrupted ();
332
+ // Retry on interrupt to avoid leaking cancellation semantics into
333
+ // IsolateDeathHandler. Closing or interrupting contexts may interrupt this
334
+ // thread.
335
+ } else {
336
+ // Fail with IsolateDeathException on repeated interrupts to avoid livelock.
337
+ throw closed ;
338
+ }
339
+ }
340
+ }
341
+ } finally {
342
+ if (interruptCount > 0 && !Thread .currentThread ().isInterrupted ()) {
343
+ Thread .currentThread ().interrupt ();
328
344
}
329
345
}
330
346
}
0 commit comments