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

(dc) Deadlock between Thread.interrupt() and DatagramChannel.send()

XMLWordPrintable

    • x86
    • windows_2012

      FULL PRODUCT VERSION :
      Both 1.7 and 1.8 JREs


      ADDITIONAL OS VERSION INFORMATION :
      Both Linux and Windows

      A DESCRIPTION OF THE PROBLEM :
      When we attempt to interrupt a thread sending data on a DatagramChannel, we sometimes encounter a deadlock between the thread doing the interrupt and the thread sending the data. We've determined that the locks in question are java.lang.Thread's blockerLock and sun.nio.ch.DatagramChannelImpl's stateLock.

      I've included a test program which can reproduce it. ~40% of the time it happens on the first iteration, otherwise it could take some time.


      REPRODUCIBILITY :
      This bug can be reproduced occasionally.

      ---------- BEGIN SOURCE ----------
      import java.io.IOException;
      import java.net.InetSocketAddress;
      import java.net.StandardSocketOptions;
      import java.nio.ByteBuffer;
      import java.nio.channels.DatagramChannel;
      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;
      import java.util.concurrent.ThreadLocalRandom;

      import org.junit.Test;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;

      public class DeadlockTest
      {
        private static final Logger LOG = LoggerFactory.getLogger(DeadlockTest.class);
        private DatagramChannel receiver;
        private InetSocketAddress target = new InetSocketAddress("localhost", 42421);
        private boolean running = true;

        private class Sender implements Runnable
        {
          private Thread thisThread = null;

          /**
           * @see java.lang.Runnable#run()
           */
          @Override
          public void run()
          {
            thisThread = Thread.currentThread();
            while (running)
            {
              try
              {
                DatagramChannel sender = DatagramChannel.open();
                sender.setOption(StandardSocketOptions.SO_REUSEADDR, true);
                sender.connect(target);

                LOG.info("Sending");
                sender.send(ByteBuffer.allocate(100).putInt(1), target);
                // Sooner or later you stop seeing this message
                LOG.info("Sent");
                Thread.sleep(ThreadLocalRandom.current().nextLong(0, 100));
              }
              catch (Exception e)
              {
                // Do Nothing
              }
              finally
              {
                if (Thread.interrupted())
                {
                  LOG.info("Was interrupted");
                }
              }
            }
          }

          public void interruptThis()
          {
            if (thisThread != null)
            {
              thisThread.interrupt();
            }
          }
        }

        @Test
        public void testDeadlock() throws IOException, InterruptedException
        {
          receiver = DatagramChannel.open();
          receiver.setOption(StandardSocketOptions.SO_REUSEADDR, true);
          receiver.bind(new InetSocketAddress(42421));
          ExecutorService executor = Executors.newSingleThreadExecutor();
          Sender senderActor = new Sender();
          executor.submit(senderActor);
          while (running)
          {
            LOG.info("Before interrupt");
            senderActor.interruptThis();
            // Sooner or later, you stop seeing this message.
            LOG.info("After interrupt");
            Thread.sleep(ThreadLocalRandom.current().nextLong(0, 100));
          }
        }
      }
      ---------- END SOURCE ----------

        1. 8138622.diff
          2 kB
        2. DeadlockTest.java
          2 kB
        3. jstack.log
          7 kB

            alanb Alan Bateman
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved: