/* 
 * Copyright 2001 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/* @test
 * @bug 4017232
 * @summary If, after returning a reference to a remote object in the current
 * VM (which gets implicitly converted to a remote stub), the client fails to
 * both send a DGC dirty call and to send a "DGC acknowledgment", the RMI
 * runtime should eventually allow the remote object to be garbage collected,
 * rather than pinning it indefinitely.
 * @author Peter Jones
 *
 * @build DGCAckFailure
 * @build DGCAckFailure_Stub
 * @run main/othervm DGCAckFailure
 */

import java.io.*;
import java.net.*;
import java.lang.ref.*;

import java.rmi.*;
import java.rmi.server.*;

interface ReturnRemote extends Remote {
    Object returnRemote() throws RemoteException;
}

public class DGCAckFailure implements ReturnRemote {

    private static final long TIMEOUT = 20000;

    public Object returnRemote() {
	return new Wrapper(this);
    }

    public static void main(String[] args) throws Exception {

	System.setProperty("sun.rmi.dgc.ackTimeout", "10000");

	/*
	 * Set a socket factory that has a hook for shutting down all client
	 * output (writes from client-created sockets and new connection
	 * attempts).  We then use this hook right before a remote stub gets
	 * deserialized, so that the client will not be able to send a DGC
	 * dirty call, or a DGC acknowledgment.  Without the DGC ack, we
	 * hope that the RMI runtime will still eventually allow the remote
	 * object to be garbage collected.
	 */
	RMISocketFactory.setSocketFactory(new TestSF());
	System.err.println("test socket factory set");

	Remote impl = new DGCAckFailure();
	ReferenceQueue refQueue = new ReferenceQueue();
	Reference weakRef = new WeakReference(impl, refQueue);
	ReturnRemote stub =
	    (ReturnRemote) UnicastRemoteObject.exportObject(impl);
	System.err.println("remote object exported; stub = " + stub);

	try {
	    Object wrappedStub = stub.returnRemote();
	    System.err.println("invocation returned: " + wrappedStub);

	    impl = null;
	    stub = null;	// in case 4114579 ever gets fixed
	    System.err.println("strong references to impl cleared");

	    System.err.println("waiting for weak reference notification:");
	    Reference ref = null;
	    for (int i = 0; i < 6; i++) {
		System.gc();
		ref = refQueue.remove(TIMEOUT / 5);
		if (ref != null) {
		    break;
		}
	    }
	    if (ref == weakRef) {
		System.err.println("TEST PASSED");
	    } else {
		throw new RuntimeException("TEST FAILED: " +
		    "timed out, remote object not garbage collected");
	    }
	} finally {
	    try {
		UnicastRemoteObject.unexportObject((Remote) weakRef.get(),
						   true);
	    } catch (Exception e) {
	    }
	}
    }

    private static class Wrapper implements Serializable {
	private final Remote obj;
	Wrapper(Remote obj) { this.obj = obj; }

	private void readObject(ObjectInputStream in)
	    throws IOException, ClassNotFoundException
	{
	    TestSF.shutdownClientOutput();
	    System.err.println(
		"Wrapper.readObject: SHUTTING DOWN CLIENT OUTPUT");
	    in.defaultReadObject();
	}

	public String toString() { return "Wrapper[" + obj + "]"; }
    }

    private static class TestSF extends RMISocketFactory {

	private static volatile boolean shutdown = false;
	static void shutdownClientOutput() { shutdown = true; }

	public Socket createSocket(String host, int port) throws IOException {
	    if (shutdown) {
		IOException e = new java.net.ConnectException(
		    "test socket factory rejecting client connection");
		System.err.println(e);
//		e.printStackTrace();
		throw e;
	    } else {
		return new TestSocket(host, port);
	    }
	}

	public ServerSocket createServerSocket(int port) throws IOException {
	    return new ServerSocket(port);
	}

	private static class TestSocket extends Socket {
	    TestSocket(String host, int port) throws IOException {
		super(host, port);
	    }
	    public OutputStream getOutputStream() throws IOException {
		return new TestOutputStream(super.getOutputStream());
	    }
	}

	private static class TestOutputStream extends FilterOutputStream {
	    TestOutputStream(OutputStream out) { super(out); }
	    public void write(int b) throws IOException {
		if (shutdown) {
		    IOException e = new IOException(
			"connection broken by test socket factory");
		    System.err.println(e);
//		    e.printStackTrace();
		    throw e;
		} else {
		    super.write(b);
		}
	    }
	}
    }
}
