diff options
author | Mark Wielaard <mark@klomp.org> | 2002-11-07 18:01:05 +0000 |
---|---|---|
committer | Mark Wielaard <mark@gcc.gnu.org> | 2002-11-07 18:01:05 +0000 |
commit | f150fe3fa7cc90fa7abd9bd64e4b5ccd6646d5a7 (patch) | |
tree | dfca54cc19c9efec9125010fd9fcb7030f24bea4 /libjava/gnu/java/rmi/server/UnicastConnectionManager.java | |
parent | 396a80436c733527118877c95bfec72e38401eeb (diff) | |
download | gcc-f150fe3fa7cc90fa7abd9bd64e4b5ccd6646d5a7.zip gcc-f150fe3fa7cc90fa7abd9bd64e4b5ccd6646d5a7.tar.gz gcc-f150fe3fa7cc90fa7abd9bd64e4b5ccd6646d5a7.tar.bz2 |
backport: MarshalledObject.java (equals): Check hashcode first.
Merge Orp RMI patches from Wu Gansha <gansha.wu@intel.com>
* java/rmi/MarshalledObject.java (equals): Check hashcode first.
* java/rmi/server/RMIClassLoader.java (MyClassLoader): Create/Use
annotation.
(loadClass): Take String as codebases.
(getClassAnnotation): Use MyClassLoader annotations.
* java/rmi/server/UnicastRemoteObject.java (UnicastRemoteObject):
call exportObject(this).
* gnu/java/rmi/RMIMarshalledObjectOutputStream.java
(RMIMarshalledObjectOutputStream): set locBytesStream and locStream.
(setAnnotation): Don't set locBytesStream and locStream.
(replaceObject): Removed.
(flush): Don't test locStream.
(getLocBytes): LikeWise.
* gnu/java/rmi/dgc/DGCImpl.java: extends UnicastServerRef.
(leaseCache): New field.
(dirty): Use leaseCache.
(LeaseRecord): New inner class.
* gnu/java/rmi/registry/RegistryImpl.java (RegistryImpl): Don't
explicitly call exportObject().
* gnu/java/rmi/registry/RegistryImpl_Stub.java: set useNewInvoke to
false to communicate with Sun JDK130.
* gnu/java/rmi/server/ConnectionRunnerPool.java: Add CPU comment.
* gnu/java/rmi/server/RMIObjectInputStream.java
(UnicastConnectionManager): Removed field.
* gnu/java/rmi/server/RMIObjectOutputStream.java (replaceObject):
Use UnicastServer.getExportedRef().
* gnu/java/rmi/server/UnicastConnection.java (reviveTime): New field.
(expireTime): Likewise.
(CONNECTION_TIMEOUT): Likewise.
(disconnect): Call sock.close().
(isExpired): New method.
(resetTime): Likewise.
(run): Use do while loop and catch Exception for discardConnection().
* gnu/java/rmi/server/UnicastConnectionManager.java: Pool connections.
* gnu/java/rmi/server/UnicastRef.java: Lots of changes.
* gnu/java/rmi/server/UnicastRemoteCall.java: Lots of changes.
* gnu/java/rmi/server/UnicastServer.java (refcache): New field.
(exportObject): Use refcache.
(unexportObject): Likewise.
(getExportedRef): New method.
* gnu/java/rmi/server/UnicastServerRef.java (UnicastServerRef): New
constructor.
(exportObject): Save manager.serverobj.
(getStub): New method.
From-SVN: r58900
Diffstat (limited to 'libjava/gnu/java/rmi/server/UnicastConnectionManager.java')
-rw-r--r-- | libjava/gnu/java/rmi/server/UnicastConnectionManager.java | 176 |
1 files changed, 160 insertions, 16 deletions
diff --git a/libjava/gnu/java/rmi/server/UnicastConnectionManager.java b/libjava/gnu/java/rmi/server/UnicastConnectionManager.java index 64fecdc..d54dcf1 100644 --- a/libjava/gnu/java/rmi/server/UnicastConnectionManager.java +++ b/libjava/gnu/java/rmi/server/UnicastConnectionManager.java @@ -1,5 +1,5 @@ /* - Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright (c) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,18 +41,25 @@ import java.rmi.server.RMISocketFactory; import java.rmi.server.RMIServerSocketFactory; import java.rmi.server.RMIClientSocketFactory; import java.rmi.RemoteException; -import gnu.java.rmi.server.UnicastConnection; -import java.util.Hashtable; -import java.net.Socket; -import java.net.ServerSocket; import java.io.IOException; import java.io.ObjectOutput; import java.io.ObjectInput; +import java.io.DataInputStream; import java.lang.Thread; import java.lang.Runnable; import java.net.InetAddress; +import java.net.Socket; +import java.net.ServerSocket; import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.ConcurrentModificationException; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; + +import gnu.java.rmi.server.UnicastConnection; + public class UnicastConnectionManager implements Runnable, ProtocolConstants { @@ -60,15 +67,33 @@ private static String localhost; // use different maps for server/client type UnicastConnectionManager private static Hashtable servers = new Hashtable(); private static Hashtable clients = new Hashtable(); +private ArrayList connections; //client connection pool // make serverThread volatile for poll private volatile Thread serverThread; private ServerSocket ssock; String serverName; int serverPort; + +static private Thread scavenger; + +// If client and server are in the same VM, serverobj represents server +Object serverobj; + +private static RMISocketFactory defaultSocketFactory = RMISocketFactory.getSocketFactory(); private RMIServerSocketFactory serverFactory; private RMIClientSocketFactory clientFactory; +// The following is for debug +private static int ncsock = 0; //count of client socket +private static int nssock = 0; //count of server socket +private static int ncmanager = 0; //count of client manager +private static int nsmanager = 0; //count of server manager + +private static final boolean debug = false; + +private static final Object GLOBAL_LOCK = new Object(); + static { try { //Use host address instead of host name to avoid name resolving issues @@ -78,16 +103,73 @@ static { catch (UnknownHostException _) { localhost = "localhost"; } + + +} + +//Only one scavenger thread running globally +private static void startScavenger(){ + scavenger = new Thread(new Runnable(){ + public void run(){ + if (debug) System.out.println("************* start scavenger."); + boolean liveon = true; + while (liveon){ + // Sleep for the expire timeout + try{ + Thread.sleep(UnicastConnection.CONNECTION_TIMEOUT); + }catch(InterruptedException _ie){ + break; + } + liveon = false; + // Scavenge all clients' connections that're expired + Iterator iter = clients.values().iterator(); + long l = System.currentTimeMillis(); + try{ + while(iter.hasNext()){ + UnicastConnectionManager man = (UnicastConnectionManager)iter.next(); + ArrayList conns = man.connections; + synchronized(conns) { // is the lock a little coarser? + for (int last = conns.size() - 1; + last >= 0; + --last) + { + UnicastConnection conn = (UnicastConnection)conns.get(last); + if (UnicastConnection.isExpired(conn, l)){ + conns.remove(last); + conn.disconnect(); + conn = null; + }else + liveon = true; //there're still live connections + } + } + } + }catch(ConcurrentModificationException cme) { + // handle it lazily + liveon = true; + } + } + scavenger = null; + if (debug) System.out.println("************* exit scavenger."); + } + }); + scavenger.start(); } +/** + * Client UnicastConnectionManager constructor + */ private UnicastConnectionManager(String host, int port, RMIClientSocketFactory csf) { ssock = null; serverName = host; serverPort = port; serverFactory = null; clientFactory = csf; + connections = new ArrayList(); } +/** + * Server UnicastConnectionManager constructor + */ private UnicastConnectionManager(int port, RMIServerSocketFactory ssf) { try { ssock = ssf.createServerSocket(port); @@ -115,7 +197,7 @@ private UnicastConnectionManager(int port, RMIServerSocketFactory ssf) { public static synchronized UnicastConnectionManager getInstance(String host, int port, RMIClientSocketFactory csf) { //System.out.println("getInstance: " + host + "," + port + "," + csf); if (csf == null) { - csf = RMISocketFactory.getSocketFactory(); + csf = defaultSocketFactory; } // change host name to host address to avoid name resolving issues try{ @@ -126,7 +208,17 @@ public static synchronized UnicastConnectionManager getInstance(String host, int UnicastConnectionManager man = (UnicastConnectionManager)clients.get(key); if (man == null) { man = new UnicastConnectionManager(host, port, csf); + if (debug) { + ncmanager++; + System.out.println("\n\n ====== " + ncmanager + " client managers.\n\n"); + } clients.put(key, man); + + // Detect if client and server are in the same VM, i.e., their keys are equal + UnicastConnectionManager svrman = (UnicastConnectionManager)servers.get(key); + if(svrman != null){ // server and client are in the same VM + man.serverobj = svrman.serverobj; + } } return (man); } @@ -138,12 +230,16 @@ public static synchronized UnicastConnectionManager getInstance(String host, int public static synchronized UnicastConnectionManager getInstance(int port, RMIServerSocketFactory ssf) { //System.out.println("getInstance: " + port + "," + ssf); if (ssf == null) { - ssf = RMISocketFactory.getSocketFactory(); + ssf = defaultSocketFactory; } TripleKey key = new TripleKey(localhost, port, ssf); UnicastConnectionManager man = (UnicastConnectionManager)servers.get(key); if (man == null) { man = new UnicastConnectionManager(port, ssf); + if (debug) { + nsmanager++; + System.out.println("\n\n ****** " + nsmanager + " server managers.\n\n"); + } // The provided port might not be the set port. key.port = man.serverPort; servers.put(key, man); @@ -168,9 +264,14 @@ public UnicastConnection getConnection() throws IOException { */ private UnicastConnection getServerConnection() throws IOException { Socket sock = ssock.accept(); + sock.setTcpNoDelay(true); //?? UnicastConnection conn = new UnicastConnection(this, sock); conn.acceptConnection(); -//System.out.println("Server connection " + conn); + if (debug){ + nssock++; + System.out.println("\n\n ****** " + nssock + " server socks.\n\n"); + } + //System.out.println("Server connection " + sock); return (conn); } @@ -178,10 +279,38 @@ private UnicastConnection getServerConnection() throws IOException { * Make a conection from this client to the server. */ private UnicastConnection getClientConnection() throws IOException { + ArrayList conns = connections; + UnicastConnection conn; + + synchronized(conns) { + int nconn = conns.size() - 1; + + // if there're free connections in connection pool + if(nconn >= 0) { + conn = (UnicastConnection)conns.get(nconn); + //Should we check if conn is alive using Ping?? + conns.remove(nconn); + + // Check if the connection is already expired + long l = System.currentTimeMillis(); + if (!UnicastConnection.isExpired(conn, l)){ + return conn; + }else { + conn.disconnect(); + conn = null; + } + } + } + Socket sock = clientFactory.createSocket(serverName, serverPort); - UnicastConnection conn = new UnicastConnection(this, sock); + conn = new UnicastConnection(this, sock); conn.makeConnection(DEFAULT_PROTOCOL); -//System.out.println("Client connection " + conn); + + if (debug) { + ncsock++; + System.out.println("\n\n ====== " + ncsock + " client socks.\n\n"); + } + return (conn); } @@ -191,7 +320,19 @@ private UnicastConnection getClientConnection() throws IOException { */ public void discardConnection(UnicastConnection conn) { //System.out.println("Discarding connection " + conn); + //conn.disconnect(); + if (ssock != null) //server connection conn.disconnect(); + else { + // To client connection, we'd like to return back to pool + UnicastConnection.resetTime(conn); + //Ensure there're only one scavenger globally + synchronized(GLOBAL_LOCK) { + connections.add(conn); //borrow this lock to garantee thread safety + if (scavenger == null) + startScavenger(); + } + } } /** @@ -204,6 +345,8 @@ public void startServer() { return; } serverThread = new Thread(this); + // The following is not necessary when java.lang.Thread's constructor do this. + // serverThread.setContextClassLoader(Thread.currentThread().getContextClassLoader()); } serverThread.start(); } @@ -231,11 +374,11 @@ public void run() { //System.out.println("Waiting for connection on " + serverPort); UnicastConnection conn = getServerConnection(); // use a thread pool to improve performance - // (new Thread(conn)).start(); - ConnectionRunnerPool.dispatchConnection(conn); + //ConnectionRunnerPool.dispatchConnection(conn); + (new Thread(conn)).start(); } catch (Exception e) { - // e.printStackTrace(); + e.printStackTrace(); } } } @@ -254,8 +397,9 @@ void write(ObjectOutput out) throws IOException { static UnicastConnectionManager read(ObjectInput in) throws IOException { String host = in.readUTF(); int port = in.readInt(); - RMIClientSocketFactory csf = ((RMIObjectInputStream)in).manager.clientFactory; - return (getInstance(host, port, csf)); + //RMIClientSocketFactory csf = ((RMIObjectInputStream)in).manager.clientFactory; + //return (getInstance(host, port, csf)); + return (getInstance(host, port, null)); } } @@ -288,7 +432,7 @@ public boolean equals(Object obj) { TripleKey other = (TripleKey)obj; if (this.host.equals(other.host) && this.other == other.other && - (this.port == other.port || this.port == 0 || other.port == 0)) { + (this.port == other.port /* || this.port == 0 || other.port == 0*/)) { return (true); } } |