HADOOP-13599. s3a close() to be non-synchronized, so avoid risk of deadlock on shutdown. Contributed by Steve Loughran.

This commit is contained in:
Chris Nauroth 2016-09-28 15:53:17 -07:00
parent 84c6264079
commit 47f80922dc
2 changed files with 15 additions and 1 deletions

View File

@ -31,6 +31,7 @@
import java.util.concurrent.ExecutorService;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
@ -121,6 +122,7 @@ public class S3AFileSystem extends FileSystem {
private S3AStorageStatistics storageStatistics;
private long readAhead;
private S3AInputPolicy inputPolicy;
private final AtomicBoolean closed = new AtomicBoolean(false);
// The maximum number of entries that can be deleted in any call to s3
private static final int MAX_ENTRIES_TO_DELETE = 1000;
@ -1414,7 +1416,11 @@ private void innerCopyFromLocalFile(boolean delSrc, boolean overwrite,
* @throws IOException IO problem
*/
@Override
public synchronized void close() throws IOException {
public void close() throws IOException {
if (closed.getAndSet(true)) {
// already closed
return;
}
try {
super.close();
} finally {

View File

@ -409,6 +409,14 @@ public void testCustomUserAgent() throws Exception {
awsConf.getUserAgent());
}
@Test
public void testCloseIdempotent() throws Throwable {
conf = new Configuration();
fs = S3ATestUtils.createTestFileSystem(conf);
fs.close();
fs.close();
}
/**
* Reads and returns a field from an object using reflection. If the field
* cannot be found, is null, or is not the expected type, then this method