History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/rmi/transport/ConnectionInputStream.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/rmi/transport/ConnectionInputStream.java+162−0
@@ -0,0 +1,162 @@
1+/*
2+ * Copyright (c) 1996, 2001, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+package sun.rmi.transport;
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
118+ * is only be safe to use c to obtain c's channel.
119+ */
120+
121+ if (dgcAckNeeded) {
122+ Connection conn = null;
123+ Channel ch = null;
124+ boolean reuse = true;
125+
126+ DGCImpl.dgcLog.log(Log.VERBOSE, "send ack");
127+
128+ try {
129+ ch = c.getChannel();
130+ conn = ch.newConnection();
131+ DataOutputStream out =
132+ new DataOutputStream(conn.getOutputStream());
133+ out.writeByte(TransportConstants.DGCAck);
134+ if (ackID == null) {
135+ ackID = new UID();
136+ }
137+ ackID.write((DataOutput) out);
138+ conn.releaseOutputStream();
139+
140+ /*
141+ * Fix for 4221173: if this connection is on top of an
142+ * HttpSendSocket, the DGCAck won't actually get sent until a
143+ * read operation is attempted on the socket. Calling
144+ * available() is the most innocuous way of triggering the
145+ * write.
146+ */
147+ conn.getInputStream().available();
148+ conn.releaseInputStream();
149+ } catch (RemoteException e) {
150+ reuse = false;
151+ } catch (IOException e) {
152+ reuse = false;
153+ }
154+ try {
155+ if (conn != null)
156+ ch.free(conn, reuse);
157+ } catch (RemoteException e){
158+ // eat exception
159+ }
160+ }
161+ }
162+}