26 27 import java.io.*; 28 import java.util.*; 29 import java.rmi.RemoteException; 30 import java.rmi.server.UID; 31 import sun.rmi.server.MarshalInputStream; 32 import sun.rmi.runtime.Log; 33 34 /** 35 * Special stream to keep track of refs being unmarshaled so that 36 * refs can be ref-counted locally. 37 * 38 * @author Ann Wollrath 39 */ 40 class ConnectionInputStream extends MarshalInputStream { 41 42 /** indicates whether ack is required for DGC */ 43 private boolean dgcAckNeeded = false; 44 45 /** Hashtable mapping Endpoints to lists of LiveRefs to register */ 46 private Map incomingRefTable = new HashMap(5); 47 48 /** identifier for gc ack*/ 49 private UID ackID; 50 51 /** 52 * Constructs a marshal input stream using the underlying 53 * stream "in". 54 */ 55 ConnectionInputStream(InputStream in) throws IOException { 56 super(in); 57 } 58 59 void readID() throws IOException { 60 ackID = UID.read((DataInput) this); 61 } 62 63 /** 64 * Save reference in order to send "dirty" call after all args/returns 65 * have been unmarshaled. Save in hashtable incomingRefTable. This 66 * table is keyed on endpoints, and holds objects of type 67 * IncomingRefTableEntry. 68 */ 69 void saveRef(LiveRef ref) { 70 Endpoint ep = ref.getEndpoint(); 71 72 // check whether endpoint is already in the hashtable 73 List refList = (List) incomingRefTable.get(ep); 74 75 if (refList == null) { 76 refList = new ArrayList(); 77 incomingRefTable.put(ep, refList); 78 } 79 80 // add ref to list of refs for endpoint ep 81 refList.add(ref); 82 } 83 84 /** 85 * Add references to DGC table (and possibly send dirty call). 86 * RegisterRefs now calls DGCClient.referenced on all 87 * refs with the same endpoint at once to achieve batching of 88 * calls to the DGC 89 */ 90 void registerRefs() throws IOException { 91 if (!incomingRefTable.isEmpty()) { 92 Set entrySet = incomingRefTable.entrySet(); 93 Iterator iter = entrySet.iterator(); 94 while (iter.hasNext()) { 95 Map.Entry entry = (Map.Entry) iter.next(); 96 Endpoint ep = (Endpoint) entry.getKey(); 97 List refList = (List) entry.getValue(); 98 DGCClient.registerRefs(ep, refList); 99 } 100 } 101 } 102 103 /** 104 * Indicate that an ack is required to the distributed 105 * collector. 106 */ 107 void setAckNeeded() { 108 dgcAckNeeded = true; 109 } 110 111 /** 112 * Done with input stream for remote call. Send DGC ack if necessary. 113 * Allow sending of ack to fail without flagging an error. 114 */ 115 void done(Connection c) { 116 /* 117 * WARNING: The connection c may have already been freed. It | 26 27 import java.io.*; 28 import java.util.*; 29 import java.rmi.RemoteException; 30 import java.rmi.server.UID; 31 import sun.rmi.server.MarshalInputStream; 32 import sun.rmi.runtime.Log; 33 34 /** 35 * Special stream to keep track of refs being unmarshaled so that 36 * refs can be ref-counted locally. 37 * 38 * @author Ann Wollrath 39 */ 40 class ConnectionInputStream extends MarshalInputStream { 41 42 /** indicates whether ack is required for DGC */ 43 private boolean dgcAckNeeded = false; 44 45 /** Hashtable mapping Endpoints to lists of LiveRefs to register */ 46 private Map<Endpoint, List<LiveRef>> incomingRefTable = new HashMap<>(5); 47 48 /** identifier for gc ack*/ 49 private UID ackID; 50 51 /** 52 * Constructs a marshal input stream using the underlying 53 * stream "in". 54 */ 55 ConnectionInputStream(InputStream in) throws IOException { 56 super(in); 57 } 58 59 void readID() throws IOException { 60 ackID = UID.read((DataInput) this); 61 } 62 63 /** 64 * Save reference in order to send "dirty" call after all args/returns 65 * have been unmarshaled. Save in hashtable incomingRefTable. This 66 * table is keyed on endpoints, and holds objects of type 67 * IncomingRefTableEntry. 68 */ 69 void saveRef(LiveRef ref) { 70 Endpoint ep = ref.getEndpoint(); 71 72 // check whether endpoint is already in the hashtable 73 List<LiveRef> refList = incomingRefTable.get(ep); 74 75 if (refList == null) { 76 refList = new ArrayList<LiveRef>(); 77 incomingRefTable.put(ep, refList); 78 } 79 80 // add ref to list of refs for endpoint ep 81 refList.add(ref); 82 } 83 84 /** 85 * Add references to DGC table (and possibly send dirty call). 86 * RegisterRefs now calls DGCClient.referenced on all 87 * refs with the same endpoint at once to achieve batching of 88 * calls to the DGC 89 */ 90 void registerRefs() throws IOException { 91 if (!incomingRefTable.isEmpty()) { 92 Set<Map.Entry<Endpoint, List<LiveRef>>> entrySet = 93 incomingRefTable.entrySet(); 94 Iterator<Map.Entry<Endpoint, List<LiveRef>>> iter = 95 entrySet.iterator(); 96 while (iter.hasNext()) { 97 Map.Entry<Endpoint, List<LiveRef>> entry = iter.next(); 98 Endpoint ep = entry.getKey(); 99 List<LiveRef> refList = entry.getValue(); 100 DGCClient.registerRefs(ep, refList); 101 } 102 } 103 } 104 105 /** 106 * Indicate that an ack is required to the distributed 107 * collector. 108 */ 109 void setAckNeeded() { 110 dgcAckNeeded = true; 111 } 112 113 /** 114 * Done with input stream for remote call. Send DGC ack if necessary. 115 * Allow sending of ack to fail without flagging an error. 116 */ 117 void done(Connection c) { 118 /* 119 * WARNING: The connection c may have already been freed. It |