Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/nio/ch/IOUtil.java
38918 views
1
/*
2
* Copyright (c) 2000, 2013, 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
26
package sun.nio.ch;
27
28
import java.io.FileDescriptor;
29
import java.io.IOException;
30
import java.nio.ByteBuffer;
31
32
33
/**
34
* File-descriptor based I/O utilities that are shared by NIO classes.
35
*/
36
37
public class IOUtil {
38
39
/**
40
* Max number of iovec structures that readv/writev supports
41
*/
42
static final int IOV_MAX;
43
44
private IOUtil() { } // No instantiation
45
46
static int write(FileDescriptor fd, ByteBuffer src, long position,
47
NativeDispatcher nd)
48
throws IOException
49
{
50
if (src instanceof DirectBuffer)
51
return writeFromNativeBuffer(fd, src, position, nd);
52
53
// Substitute a native buffer
54
int pos = src.position();
55
int lim = src.limit();
56
assert (pos <= lim);
57
int rem = (pos <= lim ? lim - pos : 0);
58
ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
59
try {
60
bb.put(src);
61
bb.flip();
62
// Do not update src until we see how many bytes were written
63
src.position(pos);
64
65
int n = writeFromNativeBuffer(fd, bb, position, nd);
66
if (n > 0) {
67
// now update src
68
src.position(pos + n);
69
}
70
return n;
71
} finally {
72
Util.offerFirstTemporaryDirectBuffer(bb);
73
}
74
}
75
76
private static int writeFromNativeBuffer(FileDescriptor fd, ByteBuffer bb,
77
long position, NativeDispatcher nd)
78
throws IOException
79
{
80
int pos = bb.position();
81
int lim = bb.limit();
82
assert (pos <= lim);
83
int rem = (pos <= lim ? lim - pos : 0);
84
85
int written = 0;
86
if (rem == 0)
87
return 0;
88
if (position != -1) {
89
written = nd.pwrite(fd,
90
((DirectBuffer)bb).address() + pos,
91
rem, position);
92
} else {
93
written = nd.write(fd, ((DirectBuffer)bb).address() + pos, rem);
94
}
95
if (written > 0)
96
bb.position(pos + written);
97
return written;
98
}
99
100
static long write(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
101
throws IOException
102
{
103
return write(fd, bufs, 0, bufs.length, nd);
104
}
105
106
static long write(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
107
NativeDispatcher nd)
108
throws IOException
109
{
110
IOVecWrapper vec = IOVecWrapper.get(length);
111
112
boolean completed = false;
113
int iov_len = 0;
114
try {
115
116
// Iterate over buffers to populate native iovec array.
117
int count = offset + length;
118
int i = offset;
119
while (i < count && iov_len < IOV_MAX) {
120
ByteBuffer buf = bufs[i];
121
int pos = buf.position();
122
int lim = buf.limit();
123
assert (pos <= lim);
124
int rem = (pos <= lim ? lim - pos : 0);
125
if (rem > 0) {
126
vec.setBuffer(iov_len, buf, pos, rem);
127
128
// allocate shadow buffer to ensure I/O is done with direct buffer
129
if (!(buf instanceof DirectBuffer)) {
130
ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
131
shadow.put(buf);
132
shadow.flip();
133
vec.setShadow(iov_len, shadow);
134
buf.position(pos); // temporarily restore position in user buffer
135
buf = shadow;
136
pos = shadow.position();
137
}
138
139
vec.putBase(iov_len, ((DirectBuffer)buf).address() + pos);
140
vec.putLen(iov_len, rem);
141
iov_len++;
142
}
143
i++;
144
}
145
if (iov_len == 0)
146
return 0L;
147
148
long bytesWritten = nd.writev(fd, vec.address, iov_len);
149
150
// Notify the buffers how many bytes were taken
151
long left = bytesWritten;
152
for (int j=0; j<iov_len; j++) {
153
if (left > 0) {
154
ByteBuffer buf = vec.getBuffer(j);
155
int pos = vec.getPosition(j);
156
int rem = vec.getRemaining(j);
157
int n = (left > rem) ? rem : (int)left;
158
buf.position(pos + n);
159
left -= n;
160
}
161
// return shadow buffers to buffer pool
162
ByteBuffer shadow = vec.getShadow(j);
163
if (shadow != null)
164
Util.offerLastTemporaryDirectBuffer(shadow);
165
vec.clearRefs(j);
166
}
167
168
completed = true;
169
return bytesWritten;
170
171
} finally {
172
// if an error occurred then clear refs to buffers and return any shadow
173
// buffers to cache
174
if (!completed) {
175
for (int j=0; j<iov_len; j++) {
176
ByteBuffer shadow = vec.getShadow(j);
177
if (shadow != null)
178
Util.offerLastTemporaryDirectBuffer(shadow);
179
vec.clearRefs(j);
180
}
181
}
182
}
183
}
184
185
static int read(FileDescriptor fd, ByteBuffer dst, long position,
186
NativeDispatcher nd)
187
throws IOException
188
{
189
if (dst.isReadOnly())
190
throw new IllegalArgumentException("Read-only buffer");
191
if (dst instanceof DirectBuffer)
192
return readIntoNativeBuffer(fd, dst, position, nd);
193
194
// Substitute a native buffer
195
ByteBuffer bb = Util.getTemporaryDirectBuffer(dst.remaining());
196
try {
197
int n = readIntoNativeBuffer(fd, bb, position, nd);
198
bb.flip();
199
if (n > 0)
200
dst.put(bb);
201
return n;
202
} finally {
203
Util.offerFirstTemporaryDirectBuffer(bb);
204
}
205
}
206
207
private static int readIntoNativeBuffer(FileDescriptor fd, ByteBuffer bb,
208
long position, NativeDispatcher nd)
209
throws IOException
210
{
211
int pos = bb.position();
212
int lim = bb.limit();
213
assert (pos <= lim);
214
int rem = (pos <= lim ? lim - pos : 0);
215
216
if (rem == 0)
217
return 0;
218
int n = 0;
219
if (position != -1) {
220
n = nd.pread(fd, ((DirectBuffer)bb).address() + pos,
221
rem, position);
222
} else {
223
n = nd.read(fd, ((DirectBuffer)bb).address() + pos, rem);
224
}
225
if (n > 0)
226
bb.position(pos + n);
227
return n;
228
}
229
230
static long read(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
231
throws IOException
232
{
233
return read(fd, bufs, 0, bufs.length, nd);
234
}
235
236
static long read(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
237
NativeDispatcher nd)
238
throws IOException
239
{
240
IOVecWrapper vec = IOVecWrapper.get(length);
241
242
boolean completed = false;
243
int iov_len = 0;
244
try {
245
246
// Iterate over buffers to populate native iovec array.
247
int count = offset + length;
248
int i = offset;
249
while (i < count && iov_len < IOV_MAX) {
250
ByteBuffer buf = bufs[i];
251
if (buf.isReadOnly())
252
throw new IllegalArgumentException("Read-only buffer");
253
int pos = buf.position();
254
int lim = buf.limit();
255
assert (pos <= lim);
256
int rem = (pos <= lim ? lim - pos : 0);
257
258
if (rem > 0) {
259
vec.setBuffer(iov_len, buf, pos, rem);
260
261
// allocate shadow buffer to ensure I/O is done with direct buffer
262
if (!(buf instanceof DirectBuffer)) {
263
ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
264
vec.setShadow(iov_len, shadow);
265
buf = shadow;
266
pos = shadow.position();
267
}
268
269
vec.putBase(iov_len, ((DirectBuffer)buf).address() + pos);
270
vec.putLen(iov_len, rem);
271
iov_len++;
272
}
273
i++;
274
}
275
if (iov_len == 0)
276
return 0L;
277
278
long bytesRead = nd.readv(fd, vec.address, iov_len);
279
280
// Notify the buffers how many bytes were read
281
long left = bytesRead;
282
for (int j=0; j<iov_len; j++) {
283
ByteBuffer shadow = vec.getShadow(j);
284
if (left > 0) {
285
ByteBuffer buf = vec.getBuffer(j);
286
int rem = vec.getRemaining(j);
287
int n = (left > rem) ? rem : (int)left;
288
if (shadow == null) {
289
int pos = vec.getPosition(j);
290
buf.position(pos + n);
291
} else {
292
shadow.limit(shadow.position() + n);
293
buf.put(shadow);
294
}
295
left -= n;
296
}
297
if (shadow != null)
298
Util.offerLastTemporaryDirectBuffer(shadow);
299
vec.clearRefs(j);
300
}
301
302
completed = true;
303
return bytesRead;
304
305
} finally {
306
// if an error occurred then clear refs to buffers and return any shadow
307
// buffers to cache
308
if (!completed) {
309
for (int j=0; j<iov_len; j++) {
310
ByteBuffer shadow = vec.getShadow(j);
311
if (shadow != null)
312
Util.offerLastTemporaryDirectBuffer(shadow);
313
vec.clearRefs(j);
314
}
315
}
316
}
317
}
318
319
public static FileDescriptor newFD(int i) {
320
FileDescriptor fd = new FileDescriptor();
321
setfdVal(fd, i);
322
return fd;
323
}
324
325
static native boolean randomBytes(byte[] someBytes);
326
327
/**
328
* Returns two file descriptors for a pipe encoded in a long.
329
* The read end of the pipe is returned in the high 32 bits,
330
* while the write end is returned in the low 32 bits.
331
*/
332
static native long makePipe(boolean blocking);
333
334
static native boolean drain(int fd) throws IOException;
335
336
public static native void configureBlocking(FileDescriptor fd,
337
boolean blocking)
338
throws IOException;
339
340
public static native int fdVal(FileDescriptor fd);
341
342
static native void setfdVal(FileDescriptor fd, int value);
343
344
static native int fdLimit();
345
346
static native int iovMax();
347
348
static native void initIDs();
349
350
/**
351
* Used to trigger loading of native libraries
352
*/
353
public static void load() { }
354
355
static {
356
java.security.AccessController.doPrivileged(
357
new java.security.PrivilegedAction<Void>() {
358
public Void run() {
359
System.loadLibrary("net");
360
System.loadLibrary("nio");
361
return null;
362
}
363
});
364
365
initIDs();
366
367
IOV_MAX = iovMax();
368
}
369
370
}
371
372