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

View File

@ -409,6 +409,14 @@ public class ITestS3AConfiguration {
awsConf.getUserAgent()); 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 * 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 * cannot be found, is null, or is not the expected type, then this method