diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/gnu/java/rmi/server/UnicastRef.java | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/gnu/java/rmi/server/UnicastRef.java')
-rw-r--r-- | libjava/classpath/gnu/java/rmi/server/UnicastRef.java | 524 |
1 files changed, 524 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastRef.java b/libjava/classpath/gnu/java/rmi/server/UnicastRef.java new file mode 100644 index 000000000..ca2bab51a --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/UnicastRef.java @@ -0,0 +1,524 @@ +/* UnicastRef.java -- + Copyright (c) 1996, 1997, 1998, 1999, 2002, 2005, 2006 + Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.rmi.server; + +import gnu.java.rmi.dgc.LeaseRenewingTask; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectInputStream; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.rmi.ConnectException; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.dgc.Lease; +import java.rmi.server.ObjID; +import java.rmi.server.Operation; +import java.rmi.server.RMIClientSocketFactory; +import java.rmi.server.RemoteCall; +import java.rmi.server.RemoteObject; +import java.rmi.server.RemoteRef; +import java.rmi.server.UID; + +public class UnicastRef + implements RemoteRef, ProtocolConstants +{ + + /** + * Use serial version UID for iteroperability + */ + private static final long serialVersionUID = 1; + + public ObjID objid; + + UnicastConnectionManager manager; + + /** + * Used by serialization, and let subclass capable of having default + * constructor + */ + // must be public otherwise java.rmi.RemoteObject cannot instantiate this + // class + // -- iP + public UnicastRef() + { + } + + public UnicastRef(ObjID objid, String host, int port, + RMIClientSocketFactory csf) + { + this(objid); + manager = UnicastConnectionManager.getInstance(host, port, csf); + } + + public UnicastRef(ObjID objid) + { + this.objid = objid; + } + + public Object invoke(Remote obj, Method method, Object[] params, long opnum) + throws Exception + { + // Check if client and server are in the same VM, then local call can be + // used to + // replace remote call, but it's somewhat violating remote semantic. + Object svrobj = manager.serverobj; + + // Make sure that the server object is compatible. It could be loaded from a + // different + // classloader --iP + if (svrobj != null && method.getDeclaringClass().isInstance(svrobj)) + { + // local call + Object ret = null; + try + { + ret = method.invoke(svrobj, params); + } + catch (InvocationTargetException e) + { + throw (Exception) e.getTargetException(); + } + // System.out.println("\n\n ***** local call: " + method + "\nreturn: " + // + ret + "\n\n"); + return ret; + } + // System.out.println("***************** remote call:" + + // manager.serverPort); + return (invokeCommon(obj, method, params, - 1, opnum)); + } + + /** + * The ordinary number of the DGC messages. + */ + static long dgcSequence; + + /** + * The DGC object id, also serves as a synchronization target to increment the + * dgcSequence safely. + */ + static final ObjID dgcId = new ObjID(ObjID.DGC_ID); + + ObjID[] this_id; + + /** + * The number of the method "dirty" in the DGC. + */ + static int DIRTY = 1; + + /** + * The DGC interface hash code. + */ + static final long dgcInterfaceHash = - 669196253586618813L; + + /** + * Notify the DGC of the remote side that we still hold this object. + */ + public Lease notifyDGC(Lease lease) throws Exception + { + long seq; + synchronized (dgcId) + { + seq = dgcSequence++; + } + + if (this_id == null) + this_id = new ObjID[] { objid }; + + UnicastConnection conn; + try + { + conn = manager.getConnection(); + } + catch (IOException e1) + { + throw new RemoteException("connection failed to host: " + + manager.serverName, e1); + } + + ObjectOutputStream out; + DataOutputStream dout; + try + { + dout = conn.getDataOutputStream(); + dout.writeByte(MESSAGE_CALL); + + out = conn.startObjectOutputStream(); // (re)start ObjectOutputStream + + dgcId.write(out); + // The number of the operation is 1 ("dirty") + out.writeInt(DIRTY); + out.writeLong(dgcInterfaceHash); + + RMIObjectOutputStream rout = (RMIObjectOutputStream) out; + + rout.writeValue(this_id, this_id.getClass()); + rout.writeLong(seq); + rout.writeValue(lease, lease.getClass()); + + out.flush(); + } + catch (IOException e2) + { + throw new RemoteException("DGC call failed: ", e2); + } + + int returncode; + Object returnval; + DataInputStream din; + ObjectInputStream in; + UID ack; + try + { + din = conn.getDataInputStream(); + + if ((returncode = din.readUnsignedByte()) != MESSAGE_CALL_ACK) + { + conn.disconnect(); + throw new RemoteException("DGC Call not acked:" + returncode); + } + + in = conn.startObjectInputStream(); // (re)start ObjectInputStream + returncode = in.readUnsignedByte(); + ack = UID.read(in); + + if (returncode == RETURN_NACK) + { + returnval = in.readObject(); // get Exception + + } + else + { + returnval = ((RMIObjectInputStream) in).readValue(Lease.class); + } + } + catch (IOException e3) + { + throw new RemoteException("DGC call return failed: ", e3); + } + + manager.discardConnection(conn); + + if (returncode != RETURN_ACK && returnval != null) + { + if (returncode == RETURN_NACK) + throw (Exception) returnval; + else + throw new RemoteException("DGC unexpected returncode: " + returncode); + } + + return (Lease) returnval; + } + /** + * Invoke the remote method on the given object. This part is overridden by + * the activatable objects. + */ + protected Object invokeCommon(Remote obj, Method method, Object[] params, + int opnum, long hash) throws Exception + { + UnicastConnection conn; + try + { + conn = manager.getConnection(); + return invokeCommon(conn, obj, method, params, opnum, hash); + } + catch (IOException e1) + { + throw new RemoteException("connection failed to host: " + + manager.serverName, e1); + } + } + + /** + * Invoke the remote method on the given object when connection is already + * established. + */ + protected Object invokeCommon(UnicastConnection conn, Remote obj, + Method method, Object[] params, int opnum, + long hash) throws Exception + { + ObjectOutputStream out; + DataOutputStream dout; + try + { + dout = conn.getDataOutputStream(); + dout.writeByte(MESSAGE_CALL); + + out = conn.startObjectOutputStream(); // (re)start ObjectOutputStream + + objid.write(out); + out.writeInt(opnum); + out.writeLong(hash); + + // must handle primitive class and their wrapper classes + Class clss[] = method.getParameterTypes(); + for (int i = 0; i < clss.length; i++) + ((RMIObjectOutputStream) out).writeValue(params[i], clss[i]); + + out.flush(); + } + catch (IOException e2) + { + throw new RemoteException("call failed: ", e2); + } + + int returncode; + Object returnval; + DataInputStream din; + ObjectInputStream in; + UID ack; + try + { + din = conn.getDataInputStream(); + + if ((returncode = din.readUnsignedByte()) != MESSAGE_CALL_ACK) + { + conn.disconnect(); + throw new RemoteException("Call not acked:" + returncode); + } + + in = conn.startObjectInputStream(); // (re)start ObjectInputStream + returncode = in.readUnsignedByte(); + ack = UID.read(in); + + Class cls = method.getReturnType(); + + if (returncode == RETURN_NACK) + { + returnval = in.readObject(); // get Exception + + } + else if (cls == Void.TYPE) + { + returnval = null; + // in.readObject() // not required! returntype 'void' means no field + // is returned. + } + else + { + returnval = ((RMIObjectInputStream) in).readValue(cls); // get + // returnvalue + } + } + catch (IOException e3) + { + // for debug: e3.printStackTrace(); + throw new RemoteException("call return failed: ", e3); + } + + /* + * if DGCAck is necessary?? //According to RMI wire protocol, send a DGCAck // + * to indicate receiving return value dout.writeByte(MESSAGE_DGCACK); + * ack.write(dout); out.flush(); + */ + + manager.discardConnection(conn); + + if (returncode != RETURN_ACK && returnval != null) + { + if (returncode == RETURN_NACK) + throw (Exception) returnval; + else + throw new RemoteException("unexpected returncode: " + returncode); + } + + return (returnval); + } + + /** + * @deprecated + */ + public RemoteCall newCall(RemoteObject obj, Operation[] op, int opnum, + long hash) throws RemoteException + { + UnicastConnection conn; + + try + { + conn = manager.getConnection(); + } + catch (IOException e1) + { + throw new ConnectException("connection failed to host: " + + manager.serverName, e1); + } + + // obj: useless? + + return (new UnicastRemoteCall(conn, objid, opnum, hash)); + } + + /** + * @deprecated + */ + public void invoke(RemoteCall call) throws Exception + { + UnicastRemoteCall c = (UnicastRemoteCall) call; + call.executeCall(); + } + + /** + * @deprecated + */ + public void done(RemoteCall call) throws RemoteException + { + UnicastRemoteCall c = (UnicastRemoteCall) call; + try + { + c.done(); + } + catch (IOException e) + { + } + UnicastConnection conn = c.getConnection(); + manager.discardConnection(conn); + } + + public void writeExternal(ObjectOutput out) throws IOException + { + if (manager == null) + { + throw new IOException("no connection"); + } + manager.write(out); + objid.write(out); + // This byte is somewhat confusing when interoperating with JDK + out.writeByte(0); // RETURN_ACK); + } + + public void readExternal(ObjectInput in) throws IOException, + ClassNotFoundException + { + manager = UnicastConnectionManager.read(in); + objid = ObjID.read(in); + byte ack = in.readByte(); + // This byte is somewhat confusing when interoperating with JDK + if (ack != RETURN_ACK && ack != 0/* jdk ack value */) + { + throw new IOException("no ack found"); + } + + // Notify the DGC of the remote side that we hold the reference to the + // received object. Do not notify if the client and server are on the + // same virtual machine. + if (manager.serverobj == null) + LeaseRenewingTask.scheduleLeases(this); + } + + public boolean remoteEquals(RemoteRef ref) + { + throw new Error("Not implemented"); + } + + public int remoteHashCode() + { + throw new Error("Not implemented"); + } + + public String getRefClass(ObjectOutput out) + { + return ("UnicastRef"); + } + + /** + * Return the string representing the remote reference information. + */ + public String remoteToString() + { + if (manager!=null) + return manager.toString(); + else + return "null manager"; + } + + public void dump(UnicastConnection conn) + { + try + { + DataInputStream din = conn.getDataInputStream(); + for (;;) + { + int b = din.readUnsignedByte(); + System.out.print(Integer.toHexString(b)); + if (b >= 32 && b < 128) + { + System.out.print(": " + (char) b); + } + System.out.println(); + } + } + catch (IOException _) + { + } + } + + /** + * Check if this UnicastRef points to the object as the passed UnicastRef. + * Both the object Id and manager must be the same. + * + * @return true if the passed reference points to the same remote object as + * this reference, false otherwise. + */ + public boolean equals(Object other) + { + if (other instanceof UnicastRef) + { + UnicastRef r = (UnicastRef) other; + return r.manager.equals(manager) && r.objid.equals(objid); + } + else + return false; + } + + /** + * Get the hash code of this UnicastRef, combining hash code of the manager + * with hash code of the object id. + */ + public int hashCode() + { + return manager.hashCode() ^ objid.hashCode(); + } + +} |