Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/SocketIOPipe.java
41161 views
1
/*
2
* Copyright (c) 2007, 2018, 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.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
package nsk.share.jpda;
24
25
import java.io.IOException;
26
import java.net.InetSocketAddress;
27
import java.net.ServerSocket;
28
import nsk.share.*;
29
30
/*
31
* This class represents communication channel based on TCP/IP sockets.
32
* Usage of this class implies creation of objects of 2 types: server SocketIOPipe object
33
* (this object creates server socket and waits for incoming connection) and client
34
* SocketIOPipe (this object attaches to server).
35
*
36
* Server and client objects should be created using special static methods provided by this class,
37
* for example 'createServerIOPipe(Log log, int port, long timeout)' for server SocketIOPipe
38
* and 'createClientIOPipe(Log log, String host, int port, long timeout)' for client SocketIOPipe.
39
*
40
* When SocketIOPipe is created it can be used to send and receive strings using methods 'readln()' and 'println(String s)'.
41
* TCP/IP connection is established at the first attempt to read or write data.
42
*
43
* For example, if client process should send string 'OK' to the server process which is run
44
* at the host 'SERVER_HOST' following code can be written:
45
*
46
* Server side:
47
*
48
* // SocketIOPipe creates ServerSocket listening given port
49
* SocketIOPipe pipe = SocketIOPipe.createServerIOPipe(log, port, timeoutValue);
50
*
51
* // SocketIOPipe waits connection from client and reads data sent by the client
52
* String command = pipe.readln();
53
*
54
* Client side:
55
*
56
* // initialize SocketIOPipe with given values of server host name and port
57
* SocketIOPipe pipe = SocketIOPipe.createClientIOPipe(log, 'SERVER_HOST', port, timeoutValue);
58
*
59
* String command = "OK";
60
* // SocketIOPipe tries to create socket and send command to the server
61
* pipe.println(command);
62
*
63
*/
64
public class SocketIOPipe extends Log.Logger implements Finalizable {
65
66
public static final int DEFAULT_TIMEOUT_VALUE = 1 * 60 * 1000;
67
68
public static final String DEFAULT_PIPE_LOG_PREFIX = "SocketIOPipe> ";
69
70
protected boolean listening;
71
72
protected String host;
73
74
protected int port;
75
76
protected long timeout;
77
78
protected SocketConnection connection;
79
80
protected volatile boolean shouldStop;
81
82
protected Process connectingProcess;
83
84
protected ServerSocket serverSocket;
85
86
protected String name;
87
88
/**
89
* Make general <code>IOPipe</code> object with specified parameters.
90
*/
91
protected SocketIOPipe(String name, Log log, String logPrefix, String host, int port, long timeout, boolean listening) {
92
super(log, logPrefix);
93
this.host = host;
94
this.port = port;
95
this.timeout = timeout;
96
this.listening = listening;
97
this.name = name;
98
}
99
100
/**
101
* Make general <code>IOPipe</code> object with specified parameters.
102
*/
103
protected SocketIOPipe(Log log, String logPrefix, String host, int port, long timeout, boolean listening) {
104
super(log, logPrefix);
105
this.host = host;
106
this.port = port;
107
this.timeout = timeout;
108
this.listening = listening;
109
}
110
111
/**
112
* Create listening SocketIOPipe using given port
113
*/
114
public static SocketIOPipe createServerIOPipe(Log log, int port, long timeout) {
115
SocketIOPipe pipe = new SocketIOPipe(log, DEFAULT_PIPE_LOG_PREFIX, null, 0, timeout, true);
116
117
try {
118
ServerSocket ss = new ServerSocket();
119
if (port == 0) {
120
// Only need SO_REUSEADDR if we're using a fixed port. If we
121
// start seeing EADDRINUSE due to collisions in free ports
122
// then we should retry the bind() a few times.
123
ss.setReuseAddress(false);
124
}
125
ss.bind(new InetSocketAddress(port));
126
pipe.setServerSocket(ss);
127
} catch (IOException e) {
128
e.printStackTrace(log.getOutStream());
129
throw new Failure("Caught IOException while binding for IOPipe connection: \n\t" + e);
130
}
131
132
return pipe;
133
}
134
135
/**
136
* Create listening SocketIOPipe using any free port
137
*/
138
public static SocketIOPipe createServerIOPipe(Log log, long timeout) {
139
return createServerIOPipe(log, 0, timeout);
140
}
141
142
/**
143
* Create attaching SocketIOPipe using given port and timeout
144
*/
145
public static SocketIOPipe createClientIOPipe(Log log, String host, int port, long timeout) {
146
return new SocketIOPipe(log, DEFAULT_PIPE_LOG_PREFIX, host, port, timeout, false);
147
}
148
149
/**
150
* Return true if <code>IOPipe</code> connection established.
151
*/
152
public boolean isConnected() {
153
return (connection != null && connection.isConnected());
154
}
155
156
/**
157
* Returns port number used by SocketIOPipe
158
*/
159
public int getPort() {
160
return port;
161
}
162
163
protected void setConnectingProcess(Process connectingProcess) {
164
this.connectingProcess = connectingProcess;
165
}
166
167
protected void setServerSocket(ServerSocket serverSocket) {
168
this.serverSocket = serverSocket;
169
if (serverSocket != null)
170
port = serverSocket.getLocalPort();
171
}
172
173
/**
174
* Write (and flush) given <code>line</code> to this
175
* <code>IOPipe</code> cnannel.
176
*
177
* @throws Failure if error occured while sending data
178
*/
179
public void println(String line) {
180
if (connection == null) {
181
connect();
182
}
183
connection.writeObject(line);
184
}
185
186
/**
187
* Read a text line from this <code>IOPipe</code> channel,
188
* or return <i>null</i> if EOF reached.
189
*
190
* @throws Failure if error occured while reading data
191
*/
192
public String readln() {
193
if (connection == null) {
194
connect();
195
}
196
String line = (String) connection.readObject();
197
return line;
198
}
199
200
/**
201
* Close this <code>IOPipe</code> connection.
202
*/
203
public void close() {
204
shouldStop = true;
205
if (connection != null) {
206
connection.close();
207
}
208
}
209
210
/**
211
* Establish <code>IOPipe</code> connection by attaching or accepting
212
* connection appropriately.
213
*/
214
protected void connect() {
215
if (connection != null) {
216
throw new TestBug("IOPipe connection is already established");
217
}
218
219
if (shouldStop)
220
return;
221
222
connection = new SocketConnection(this, getName());
223
224
if (listening) {
225
connection.setConnectingProcess(connectingProcess);
226
if (serverSocket == null) {
227
connection.bind(port, timeout);
228
} else {
229
connection.setServerSocket(serverSocket);
230
}
231
232
if (shouldStop)
233
return;
234
235
// wait for connection from remote host
236
connection.accept(timeout);
237
238
} else {
239
// attach from the debuggee's side
240
connection.continueAttach(host, port, timeout);
241
}
242
}
243
244
/**
245
* Set ping timeout in milliseconds (0 means don't use ping at all).
246
*/
247
public void setPingTimeout(long timeout) {
248
if (connection == null) {
249
throw new TestBug("Attempt to set ping timeout for not established connection");
250
}
251
connection.setPingTimeout(timeout);
252
}
253
254
/**
255
* Returns value of current ping timeout in milliseconds (0 means ping is not used).
256
*/
257
public long getPingTimeout() {
258
if (connection == null) {
259
throw new TestBug("Attempt to get ping timeout for not established connection");
260
}
261
return connection.getPingTimeout();
262
}
263
264
/**
265
* Perform finalization of the object by invoking close().
266
*/
267
protected void finalize() throws Throwable {
268
close();
269
super.finalize();
270
}
271
272
/**
273
* Perform finalization of the object at exit by invoking finalize().
274
*/
275
public void finalizeAtExit() throws Throwable {
276
finalize();
277
}
278
279
/**
280
* Field 'pipeCounter' and method 'getNextPipeNumber' are used to construct unique names for SocketIOPipes
281
*/
282
private static int pipeCounter;
283
284
private synchronized int getNextPipeNumber() {
285
return pipeCounter++;
286
}
287
288
/**
289
* Construct name for SocketIOPipe if it wasn't specified
290
*/
291
private String getName() {
292
if (name == null) {
293
name = "SocketIOPipe-" + getNextPipeNumber();
294
}
295
296
return name;
297
}
298
}
299
300