aboutsummaryrefslogtreecommitdiff
path: root/libjava/gnu/java/rmi/server/UnicastConnectionManager.java
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2002-11-07 18:01:05 +0000
committerMark Wielaard <mark@gcc.gnu.org>2002-11-07 18:01:05 +0000
commitf150fe3fa7cc90fa7abd9bd64e4b5ccd6646d5a7 (patch)
treedfca54cc19c9efec9125010fd9fcb7030f24bea4 /libjava/gnu/java/rmi/server/UnicastConnectionManager.java
parent396a80436c733527118877c95bfec72e38401eeb (diff)
downloadgcc-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.java176
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);
}
}