@@ -121,6 +121,8 @@ final class ProcessIsolateThreadSupport {
121121 private static final int INITIAL_REQUEST_CACHE_SIZE = 1 << 10 ;
122122 private static final int MAX_REQUEST_CACHE_SIZE = 1 << 20 ;
123123
124+ private static final int MAX_INTERRUPTED_ATTACH_RETRIES = 10 ;
125+
124126 private final DispatchSupport dispatchSupport ;
125127 private final ServerSocketChannel local ;
126128 private UnixDomainSocketAddress peer ;
@@ -316,15 +318,29 @@ ThreadChannel attachThread() throws IOException {
316318 * and {@code Context.interrupt()} interrupt threads.
317319 */
318320 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 ();
328344 }
329345 }
330346 }
0 commit comments