/*
 * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/**
 * @test
 * @bug 4796166
 * @summary Linger interval delays usage of released file descriptor
 */

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

public class LingerTest {

    static class Sender implements Runnable {
        Socket s;

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

        public void run() {
            System.out.println ("Sender starts");
            try {
                s.getOutputStream().write(new byte[128*1024]);
            }
            catch (IOException ioe) {
            }
            System.out.println ("Sender ends");
        }
    }

    static class Closer implements Runnable {
        Socket s;

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

        public void run() {
            System.out.println ("Closer starts");
            try {
                s.close();
            }
            catch (IOException ioe) {
            }
            System.out.println ("Closer ends");
        }
    }

    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() {
            System.out.println ("Another starts");
            try {
                Thread.currentThread().sleep(delay);
                Socket s = new Socket("localhost", port);
                synchronized (this) {
                    connected = true;
                }
                s.close();
            }
            catch (Exception ioe) {
                ioe.printStackTrace();
            }
            System.out.println ("Another ends");
        }

        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");
        }
        System.out.println ("Main ends");

    }

}
