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

(ch) ChannelInputStream hangs in native method SocketDispatcher::read0

XMLWordPrintable

    • x86_64
    • windows

      ADDITIONAL SYSTEM INFORMATION :
      Windows Server 2019/2022 / jdk-17.0.6_10

      A DESCRIPTION OF THE PROBLEM :
      Consider the following code shnipped:

            SelectorProvider selectorProvider = SelectorProvider.provider(); // default SelectorProvider is WEPollSelectorProvider
            final Pipe pipe = selectorProvider.openPipe();
            final InputStream is = Channels.newInputStream(pipe.source());
            final OutputStream os = Channels.newOutputStream(pipe.sink());

      The problem occurs under the following conditions (only on Windows, not on Linux):
      - A "writer" thread is startet in order to write content to the OutputStream
      - A "reader" thread waits on "read" before the writer thread is started or finished
      - The content size is ~ 33kb (or more)

      Somtimes, the "reader thread" hangs at the following native function:

      at sun.nio.ch.SocketDispatcher.read0(java.base@17.0.6/Native Method)
      at sun.nio.ch.SocketDispatcher.read(java.base@17.0.6/SocketDispatcher.java:46)
      at sun.nio.ch.IOUtil.readIntoNativeBuffer(java.base@17.0.6/IOUtil.java:330)
      at sun.nio.ch.IOUtil.read(java.base@17.0.6/IOUtil.java:296)
      at sun.nio.ch.IOUtil.read(java.base@17.0.6/IOUtil.java:259)
      at sun.nio.ch.SocketChannelImpl.read(java.base@17.0.6/SocketChannelImpl.java:417)
      at sun.nio.ch.SourceChannelImpl.read(java.base@17.0.6/SourceChannelImpl.java:113)
      at sun.nio.ch.ChannelInputStream.read(java.base@17.0.6/ChannelInputStream.java:59)
      - locked <0x0000000413245218> (a java.lang.Object)
      at sun.nio.ch.ChannelInputStream.read(java.base@17.0.6/ChannelInputStream.java:107)
      at sun.nio.ch.ChannelInputStream.read(java.base@17.0.6/ChannelInputStream.java:101)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Execute the given source code and increase the number of iterations if the problem does not occur (and/or modify the size of your intput file).

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The "reader" is always able to receive content from the pipe source.
      ACTUAL -
      The "reader" sometimes hangs while receiving content from the pipe source.

      ---------- BEGIN SOURCE ----------

      import java.io.BufferedInputStream;
      import java.io.FileInputStream;
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.OutputStream;
      import java.nio.channels.Channels;
      import java.nio.channels.Pipe;
      import java.nio.channels.spi.SelectorProvider;
      import java.util.List;
      import java.util.concurrent.Callable;
      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;

      import org.apache.commons.io.IOUtils;

      public class Test
      {
        public static void main(String[] x) throws Exception
        {
          for (int i = 0; i < 200; i++)
          {
            SelectorProvider selectorProvider = SelectorProvider.provider();
            final Pipe pipe = selectorProvider.openPipe();
            final InputStream is = Channels.newInputStream(pipe.source());
            final OutputStream os = Channels.newOutputStream(pipe.sink());
            final int index = i + 1;

            new Thread(() ->
            {
              try
              {
                try
                {
                  Thread.sleep(200);
                }
                catch (InterruptedException aE)
                {
                  throw new RuntimeException(aE);
                }
                try (
                    InputStream inputStream = new BufferedInputStream(new FileInputStream("C:/a_file_with_33kb_content.txt"));
                    os)
                {
                  IOUtils.copy(inputStream, os);
                }
                System.out.println("WRITTEN for iteration " + index);
              }
              catch (IOException aE)
              {
                throw new RuntimeException(aE);
              }
            }).start();

            try (is)
            {
              final String output = new String(is.readAllBytes());
              System.out.println("READ for iteration" + index);
            }
          }
        }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Make sure that the "writer" thread has finished before the "reader" thread starts waiting (does not work for large content of cause).

      FREQUENCY : often


            bpb Brian Burkhalter
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: