mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8220477: Channels.newWriter() does not close if underlying channel throws an IOException
Reviewed-by: alanb
This commit is contained in:
parent
7b7f9a6fd3
commit
69ca2e9e27
3 changed files with 142 additions and 22 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -28,10 +28,20 @@
|
||||||
|
|
||||||
package sun.nio.cs;
|
package sun.nio.cs;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.FileInputStream;
|
||||||
import java.nio.*;
|
import java.io.IOException;
|
||||||
import java.nio.channels.*;
|
import java.io.InputStream;
|
||||||
import java.nio.charset.*;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.CharBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.CharsetDecoder;
|
||||||
|
import java.nio.charset.CoderResult;
|
||||||
|
import java.nio.charset.CodingErrorAction;
|
||||||
|
import java.nio.charset.IllegalCharsetNameException;
|
||||||
|
|
||||||
public class StreamDecoder extends Reader
|
public class StreamDecoder extends Reader
|
||||||
{
|
{
|
||||||
|
@ -190,8 +200,11 @@ public class StreamDecoder extends Reader
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
if (closed)
|
if (closed)
|
||||||
return;
|
return;
|
||||||
implClose();
|
try {
|
||||||
closed = true;
|
implClose();
|
||||||
|
} finally {
|
||||||
|
closed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -23,15 +23,21 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package sun.nio.cs;
|
package sun.nio.cs;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.FileOutputStream;
|
||||||
import java.nio.*;
|
import java.io.IOException;
|
||||||
import java.nio.channels.*;
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.*;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.CharBuffer;
|
||||||
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.CharsetEncoder;
|
||||||
|
import java.nio.charset.CoderResult;
|
||||||
|
import java.nio.charset.CodingErrorAction;
|
||||||
|
import java.nio.charset.IllegalCharsetNameException;
|
||||||
|
|
||||||
public class StreamEncoder extends Writer
|
public class StreamEncoder extends Writer
|
||||||
{
|
{
|
||||||
|
@ -158,8 +164,11 @@ public class StreamEncoder extends Writer
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
if (closed)
|
if (closed)
|
||||||
return;
|
return;
|
||||||
implClose();
|
try {
|
||||||
closed = true;
|
implClose();
|
||||||
|
} finally {
|
||||||
|
closed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,8 +346,13 @@ public class StreamEncoder extends Writer
|
||||||
writeBytes();
|
writeBytes();
|
||||||
if (ch != null)
|
if (ch != null)
|
||||||
ch.close();
|
ch.close();
|
||||||
else
|
else {
|
||||||
out.close();
|
try {
|
||||||
|
out.flush();
|
||||||
|
} finally {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (IOException x) {
|
} catch (IOException x) {
|
||||||
encoder.reset();
|
encoder.reset();
|
||||||
throw x;
|
throw x;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* @test
|
/* @test
|
||||||
* @bug 4417152 4481572 6248930 6725399 6884800
|
* @bug 4417152 4481572 6248930 6725399 6884800 8220477
|
||||||
* @summary Test Channels basic functionality
|
* @summary Test Channels basic functionality
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@ import java.nio.*;
|
||||||
import java.nio.charset.*;
|
import java.nio.charset.*;
|
||||||
import java.nio.channels.*;
|
import java.nio.channels.*;
|
||||||
|
|
||||||
|
|
||||||
public class Basic {
|
public class Basic {
|
||||||
|
|
||||||
static String message;
|
static String message;
|
||||||
|
@ -204,6 +203,8 @@ public class Basic {
|
||||||
writeOut(blah, ITERATIONS);
|
writeOut(blah, ITERATIONS);
|
||||||
testNewReader(blah);
|
testNewReader(blah);
|
||||||
|
|
||||||
|
testNewWriterClose();
|
||||||
|
testNewReaderClose();
|
||||||
} finally {
|
} finally {
|
||||||
blah.delete();
|
blah.delete();
|
||||||
}
|
}
|
||||||
|
@ -399,6 +400,98 @@ public class Basic {
|
||||||
r.close();
|
r.close();
|
||||||
fis.close();
|
fis.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void testNewWriterClose() throws Exception {
|
||||||
|
Writer writer = null;
|
||||||
|
try {
|
||||||
|
WritableByteChannel channel = new WritableByteChannel() {
|
||||||
|
@Override
|
||||||
|
public int write(ByteBuffer src) throws IOException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOpen() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
writer = Channels.newWriter(channel,
|
||||||
|
StandardCharsets.UTF_8.newEncoder(), -1);
|
||||||
|
writer.close();
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
Exception theException = null;
|
||||||
|
try {
|
||||||
|
writer.write(1);
|
||||||
|
writer.flush();
|
||||||
|
} catch (Exception e) {
|
||||||
|
theException = e;
|
||||||
|
} finally {
|
||||||
|
if (theException == null) {
|
||||||
|
throw new RuntimeException("IOException not thrown");
|
||||||
|
} else if (!(theException instanceof IOException)) {
|
||||||
|
throw new RuntimeException("Exception not an IOException: "
|
||||||
|
+ theException);
|
||||||
|
} else {
|
||||||
|
String message = theException.getMessage();
|
||||||
|
if (!message.equals("Stream closed")) {
|
||||||
|
throw new RuntimeException("Unexpected message "
|
||||||
|
+ message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void testNewReaderClose() throws Exception {
|
||||||
|
Reader reader = null;
|
||||||
|
try {
|
||||||
|
ReadableByteChannel channel = new ReadableByteChannel() {
|
||||||
|
@Override
|
||||||
|
public int read(ByteBuffer dst) throws IOException {
|
||||||
|
dst.put((byte)7);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOpen() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reader = Channels.newReader(channel,
|
||||||
|
StandardCharsets.UTF_8.newDecoder(), -1);
|
||||||
|
reader.close();
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
Exception theException = null;
|
||||||
|
try {
|
||||||
|
reader.read();
|
||||||
|
} catch (Exception e) {
|
||||||
|
theException = e;
|
||||||
|
} finally {
|
||||||
|
if (theException == null) {
|
||||||
|
throw new RuntimeException("IOException not thrown");
|
||||||
|
} else if (!(theException instanceof IOException)) {
|
||||||
|
throw new RuntimeException("Exception not an IOException: "
|
||||||
|
+ theException);
|
||||||
|
} else {
|
||||||
|
String message = theException.getMessage();
|
||||||
|
if (!message.equals("Stream closed")) {
|
||||||
|
throw new RuntimeException("Unexpected message "
|
||||||
|
+ message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExtendedFileInputStream extends java.io.FileInputStream {
|
class ExtendedFileInputStream extends java.io.FileInputStream {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue