Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.rmi/share/classes/sun/rmi/transport/ConnectionInputStream.java
41154 views
1
/*
2
* Copyright (c) 1996, 2017, 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<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
* Discard the saved incoming refs so there is nothing to register
86
* when {@code registerRefs} is called.
87
*/
88
void discardRefs() {
89
incomingRefTable.clear();
90
}
91
92
/**
93
* Add references to DGC table (and possibly send dirty call).
94
* RegisterRefs now calls DGCClient.referenced on all
95
* refs with the same endpoint at once to achieve batching of
96
* calls to the DGC
97
*/
98
void registerRefs() throws IOException {
99
if (!incomingRefTable.isEmpty()) {
100
for (Map.Entry<Endpoint, List<LiveRef>> entry :
101
incomingRefTable.entrySet()) {
102
DGCClient.registerRefs(entry.getKey(), entry.getValue());
103
}
104
}
105
}
106
107
/**
108
* Indicate that an ack is required to the distributed
109
* collector.
110
*/
111
void setAckNeeded() {
112
dgcAckNeeded = true;
113
}
114
115
/**
116
* Done with input stream for remote call. Send DGC ack if necessary.
117
* Allow sending of ack to fail without flagging an error.
118
*/
119
void done(Connection c) {
120
/*
121
* WARNING: The connection c may have already been freed. It
122
* is only be safe to use c to obtain c's channel.
123
*/
124
125
if (dgcAckNeeded) {
126
Connection conn = null;
127
Channel ch = null;
128
boolean reuse = true;
129
130
DGCImpl.dgcLog.log(Log.VERBOSE, "send ack");
131
132
try {
133
ch = c.getChannel();
134
conn = ch.newConnection();
135
DataOutputStream out =
136
new DataOutputStream(conn.getOutputStream());
137
out.writeByte(TransportConstants.DGCAck);
138
if (ackID == null) {
139
ackID = new UID();
140
}
141
ackID.write((DataOutput) out);
142
conn.releaseOutputStream();
143
144
/*
145
* Fix for 4221173: if this connection is on top of an
146
* HttpSendSocket, the DGCAck won't actually get sent until a
147
* read operation is attempted on the socket. Calling
148
* available() is the most innocuous way of triggering the
149
* write.
150
*/
151
conn.getInputStream().available();
152
conn.releaseInputStream();
153
} catch (RemoteException e) {
154
reuse = false;
155
} catch (IOException e) {
156
reuse = false;
157
}
158
try {
159
if (conn != null)
160
ch.free(conn, reuse);
161
} catch (RemoteException e){
162
// eat exception
163
}
164
}
165
}
166
}
167
168