src/share/classes/sun/rmi/transport/ConnectionInputStream.java

Print this page




  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