Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8371045

Socket I/O during class loading in a virtual thread may cause a deadlock

XMLWordPrintable

    • b23
    • 22
    • generic
    • linux

      A DESCRIPTION OF THE PROBLEM :
      Socket uses `sun.nio.ch.Poller` to handle I/O operations.
      In JDK 25, a new mode was added that uses virtual threads as I/O worker. When running in a Linux environment or system property 'jdk.pollerMode' is '2', 'Mode.VTHREAD_POLLERS' will be selected, in which case virtual threads will be used.
      The following is the JDK source code:

      ------sun.nio.ch.Poller source code begin---------------------
        Pollers() throws IOException {
                  PollerProvider provider = PollerProvider.provider();
                  Poller.Mode mode;
                  String s = System.getProperty("jdk.pollerMode");
                  if (s != null) {
                      if (s.equalsIgnoreCase(Mode.SYSTEM_THREADS.name()) || s.equals("1")) {
                          mode = Mode.SYSTEM_THREADS;
                      } else if (s.equalsIgnoreCase(Mode.VTHREAD_POLLERS.name()) || s.equals("2")) {
                          mode = Mode.VTHREAD_POLLERS;
                      } else {
                          throw new RuntimeException("Can't parse '" + s + "' as polling mode");
                      }
                  } else {
                      mode = provider.defaultPollerMode();
                  }
      ------source code end---------------------

      But class loading running in virtual thread of JDK 25 still bring thread pinning
      When all carrier threads are pinned by virtual threads which are waiting class loading, if a socket operation needs to be performed during class loading, the Poller handling this socket operation will be unable to acquire a carrier thread.
      This will result in a request failure, and in the worst case, a deadlock will occur, class loading will never complete

      This can be reproduced through code.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      run the code below:
      ---------- BEGIN SOURCE ----------
      import java.net.InetSocketAddress;
      import java.net.Socket;
      import java.util.concurrent.CountDownLatch;

      public class Test{
          static void main() throws Exception {
              String isLinux = System.getProperty("os.name").toLowerCase();
              if (!isLinux.contains("linux")) {
                  System.setProperty("jdk.pollerMode", "2");
              }

              int parallelism = Runtime.getRuntime().availableProcessors();
              CountDownLatch latch = new CountDownLatch(parallelism);

              System.out.println("checkpoint");

              for (int i = 0; i < parallelism; i++) {
                  Thread.startVirtualThread(() -> {
                      try {
                          new Tcp();//call Socket.connect during class loading
                      } finally {
                          latch.countDown();
                      }
                  });
              }
              Thread.sleep(10);

              latch.await();
              System.out.println("All tasks completed");
          }

          static class Tcp {
              static {
                  try (Socket socket = new Socket()) {
                      socket.connect(new InetSocketAddress("bugreport.java.com", 443));
                      System.out.println("Connected to bugreport.java.com");
                  } catch (Exception e) {

                  }
              }
          }
      }


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      -------------ouput in console:------------
      checkpoint
      Connected to bugreport.java.com
      All tasks completed
      ACTUAL -
      -------------ouput in console:------------
      checkpoint

      //the proceess will never complete

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: