Skip to content

Commit 7838321

Browse files
author
Alan Bateman
committed
8358496: Concurrent reading from Socket with timeout executes sequentially
Reviewed-by: dfuchs
1 parent 42f48a3 commit 7838321

File tree

2 files changed

+163
-106
lines changed

2 files changed

+163
-106
lines changed

src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -288,19 +288,18 @@ private int timedRead(FileDescriptor fd, byte[] b, int off, int len, long nanos)
288288
* @throws SocketException if the socket is closed or a socket I/O error occurs
289289
* @throws SocketTimeoutException if the read timeout elapses
290290
*/
291-
private int implRead(byte[] b, int off, int len) throws IOException {
291+
private int implRead(byte[] b, int off, int len, long remainingNanos) throws IOException {
292292
int n = 0;
293293
FileDescriptor fd = beginRead();
294294
try {
295295
if (connectionReset)
296296
throw new SocketException("Connection reset");
297297
if (isInputClosed)
298298
return -1;
299-
int timeout = this.timeout;
300-
configureNonBlockingIfNeeded(fd, timeout > 0);
301-
if (timeout > 0) {
299+
configureNonBlockingIfNeeded(fd, remainingNanos > 0);
300+
if (remainingNanos > 0) {
302301
// read with timeout
303-
n = timedRead(fd, b, off, len, MILLISECONDS.toNanos(timeout));
302+
n = timedRead(fd, b, off, len, remainingNanos);
304303
} else {
305304
// read, no timeout
306305
n = tryRead(fd, b, off, len);
@@ -335,14 +334,24 @@ private int read(byte[] b, int off, int len) throws IOException {
335334
if (len == 0) {
336335
return 0;
337336
} else {
338-
readLock.lock();
337+
long remainingNanos = 0;
338+
int timeout = this.timeout;
339+
if (timeout > 0) {
340+
remainingNanos = tryLock(readLock, timeout, MILLISECONDS);
341+
if (remainingNanos <= 0) {
342+
assert !readLock.isHeldByCurrentThread();
343+
throw new SocketTimeoutException("Read timed out");
344+
}
345+
} else {
346+
readLock.lock();
347+
}
339348
try {
340349
// emulate legacy behavior to return -1, even if socket is closed
341350
if (readEOF)
342351
return -1;
343352
// read up to MAX_BUFFER_SIZE bytes
344353
int size = Math.min(len, MAX_BUFFER_SIZE);
345-
int n = implRead(b, off, size);
354+
int n = implRead(b, off, size, remainingNanos);
346355
if (n == -1)
347356
readEOF = true;
348357
return n;

0 commit comments

Comments
 (0)