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

Linger interval delays usage of released file descriptor

    XMLWordPrintable

Details

    • 03
    • generic
    • linux_redhat_7.1

    Backports

      Description

        We have a bug in Linux close mechanism whereby a lengthy linger interval
        will block re-usage of a released file descriptor until the linger
        interval expires.

        The issue is that Linux's close call releases the file descriptor before
        the linger interval expires. This allows the file descriptor to be re-used
        by another newly created Socket but I/O on the newly created Socket will
        be blocked until the linger interval for the previous usage expires. The
        issue is specific to java.net.Socket.

        The following test case demonstrates the issue (sorry I didn't have time
        to clean it up - Alan) :-

        import java.net.*;
        import java.io.*;

        public class Test {

            static class Sender implements Runnable {
                Socket s;

                public Sender(Socket s) {
                    this.s = s;
                }

                public void run() {
                    try {
                        s.getOutputStream().write(new byte[128*1024]);
                    } catch (IOException ioe) {
                    }
                }
            }

            static class Closer implements Runnable {
                Socket s;

                public Closer(Socket s) {
                    this.s = s;
                }

                public void run() {
                    try {
                        s.close();
                    } catch (IOException ioe) {
                    }
                }
            }

            static class Another implements Runnable {
                int port;
                long delay;
                boolean connected = false;

                public Another(int port, long delay) {
                    this.port = port;
                    this.delay = delay;
                }

                public void run() {
                    try {
                        Thread.currentThread().sleep(delay);
                        Socket s = new Socket("localhost", port);
                        synchronized (this) {
                            connected = true;
                        }
                        s.close();
                    } catch (Exception ioe) {
                        ioe.printStackTrace();
                    }
                }

                public synchronized boolean connected() {
                    return connected;
                }
            }

            public static void main(String args[]) throws Exception {
                ServerSocket ss = new ServerSocket(0);

                Socket s1 = new Socket("localhost", ss.getLocalPort());
                Socket s2 = ss.accept();


                // setup conditions for untransmitted data and lengthy
                // linger interval
                s1.setSendBufferSize(128*1024);
                s1.setSoLinger(true, 30);
                s2.setReceiveBufferSize(1*1024);

                // start sender
                Thread thr = new Thread(new Sender(s1));
                thr.start();

                // another thread that will connect after 5 seconds.
                Another another = new Another(ss.getLocalPort(), 5000);
                thr = new Thread(another);
                thr.start();

                // give sender time to queue the data
                Thread.currentThread().sleep(1000);

                // close the socket asynchronously
                (new Thread(new Closer(s1))).start();

                // give another time to run
                Thread.currentThread().sleep(10000);

                // check that another is done
                if (!another.connected()) {
                    throw new RuntimeException("Another thread is blocked");
                }

            }

        }

        Attachments

          Issue Links

            Activity

              People

                michaelm Michael McMahon
                alanb Alan Bateman
                Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: