HADOOP-7256. Resource leak during failure scenario of closing of resources. Contributed by Ramkrishna S. Vasudevan. (harsh)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1388893 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Harsh J 2012-09-22 20:34:16 +00:00
parent bd76d9a827
commit 28023b7759
3 changed files with 41 additions and 4 deletions

View File

@ -215,6 +215,9 @@ Trunk (Unreleased)
HADOOP-8821. Fix findbugs warning related to concatenating string in a HADOOP-8821. Fix findbugs warning related to concatenating string in a
for loop in Configuration#dumpDeprecatedKeys(). (suresh) for loop in Configuration#dumpDeprecatedKeys(). (suresh)
HADOOP-7256. Resource leak during failure scenario of closing
of resources. (Ramkrishna S. Vasudevan via harsh)
OPTIMIZATIONS OPTIMIZATIONS
HADOOP-7761. Improve the performance of raw comparisons. (todd) HADOOP-7761. Improve the performance of raw comparisons. (todd)

View File

@ -25,6 +25,7 @@ import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel; import java.nio.channels.WritableByteChannel;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.classification.InterfaceStability;
@ -36,6 +37,7 @@ import org.apache.hadoop.conf.Configuration;
@InterfaceAudience.Public @InterfaceAudience.Public
@InterfaceStability.Evolving @InterfaceStability.Evolving
public class IOUtils { public class IOUtils {
public static final Log LOG = LogFactory.getLog(IOUtils.class);
/** /**
* Copies from one stream to another. * Copies from one stream to another.
@ -235,7 +237,7 @@ public class IOUtils {
if (c != null) { if (c != null) {
try { try {
c.close(); c.close();
} catch(IOException e) { } catch(Throwable e) {
if (log != null && log.isDebugEnabled()) { if (log != null && log.isDebugEnabled()) {
log.debug("Exception in closing " + c, e); log.debug("Exception in closing " + c, e);
} }
@ -264,6 +266,7 @@ public class IOUtils {
try { try {
sock.close(); sock.close();
} catch (IOException ignored) { } catch (IOException ignored) {
LOG.debug("Ignoring exception while closing socket", ignored);
} }
} }
} }

View File

@ -66,6 +66,36 @@ public class TestIOUtils {
Mockito.verify(outputStream, Mockito.atLeastOnce()).close(); Mockito.verify(outputStream, Mockito.atLeastOnce()).close();
} }
@Test
public void testCopyBytesShouldCloseInputSteamWhenOutputStreamCloseThrowsRunTimeException()
throws Exception {
InputStream inputStream = Mockito.mock(InputStream.class);
OutputStream outputStream = Mockito.mock(OutputStream.class);
Mockito.doReturn(-1).when(inputStream).read(new byte[1]);
Mockito.doThrow(new RuntimeException()).when(outputStream).close();
try {
IOUtils.copyBytes(inputStream, outputStream, 1, true);
fail("Didn't throw exception");
} catch (RuntimeException e) {
}
Mockito.verify(outputStream, Mockito.atLeastOnce()).close();
}
@Test
public void testCopyBytesShouldCloseInputSteamWhenInputStreamCloseThrowsRunTimeException()
throws Exception {
InputStream inputStream = Mockito.mock(InputStream.class);
OutputStream outputStream = Mockito.mock(OutputStream.class);
Mockito.doReturn(-1).when(inputStream).read(new byte[1]);
Mockito.doThrow(new RuntimeException()).when(inputStream).close();
try {
IOUtils.copyBytes(inputStream, outputStream, 1, true);
fail("Didn't throw exception");
} catch (RuntimeException e) {
}
Mockito.verify(inputStream, Mockito.atLeastOnce()).close();
}
@Test @Test
public void testCopyBytesShouldNotCloseStreamsWhenCloseIsFalse() public void testCopyBytesShouldNotCloseStreamsWhenCloseIsFalse()
throws Exception { throws Exception {
@ -76,7 +106,7 @@ public class TestIOUtils {
Mockito.verify(inputStream, Mockito.atMost(0)).close(); Mockito.verify(inputStream, Mockito.atMost(0)).close();
Mockito.verify(outputStream, Mockito.atMost(0)).close(); Mockito.verify(outputStream, Mockito.atMost(0)).close();
} }
@Test @Test
public void testCopyBytesWithCountShouldCloseStreamsWhenCloseIsTrue() public void testCopyBytesWithCountShouldCloseStreamsWhenCloseIsTrue()
throws Exception { throws Exception {
@ -117,7 +147,7 @@ public class TestIOUtils {
Mockito.verify(inputStream, Mockito.atLeastOnce()).close(); Mockito.verify(inputStream, Mockito.atLeastOnce()).close();
Mockito.verify(outputStream, Mockito.atLeastOnce()).close(); Mockito.verify(outputStream, Mockito.atLeastOnce()).close();
} }
@Test @Test
public void testWriteFully() throws IOException { public void testWriteFully() throws IOException {
final int INPUT_BUFFER_LEN = 10000; final int INPUT_BUFFER_LEN = 10000;
@ -148,6 +178,7 @@ public class TestIOUtils {
for (int i = HALFWAY; i < input.length; i++) { for (int i = HALFWAY; i < input.length; i++) {
assertEquals(input[i - HALFWAY], output[i]); assertEquals(input[i - HALFWAY], output[i]);
} }
raf.close();
} finally { } finally {
File f = new File(TEST_FILE_NAME); File f = new File(TEST_FILE_NAME);
if (f.exists()) { if (f.exists()) {
@ -177,7 +208,7 @@ public class TestIOUtils {
"Error while reading compressed data", ioe); "Error while reading compressed data", ioe);
} }
} }
@Test @Test
public void testSkipFully() throws IOException { public void testSkipFully() throws IOException {
byte inArray[] = new byte[] {0, 1, 2, 3, 4}; byte inArray[] = new byte[] {0, 1, 2, 3, 4};