MAPREDUCE-7441. Fix race condition in closing FadvisedFileRegion. Contributed by Benjamin Teke
This commit is contained in:
parent
eb88b9ff21
commit
1c15987ee3
@ -41,6 +41,7 @@ public class FadvisedFileRegion extends DefaultFileRegion {
|
||||
private static final Logger LOG =
|
||||
LoggerFactory.getLogger(FadvisedFileRegion.class);
|
||||
|
||||
private final Object closeLock = new Object();
|
||||
private final boolean manageOsCache;
|
||||
private final int readaheadLength;
|
||||
private final ReadaheadPool readaheadPool;
|
||||
@ -52,7 +53,7 @@ public class FadvisedFileRegion extends DefaultFileRegion {
|
||||
private final boolean shuffleTransferToAllowed;
|
||||
private final FileChannel fileChannel;
|
||||
|
||||
private ReadaheadRequest readaheadRequest;
|
||||
private volatile ReadaheadRequest readaheadRequest;
|
||||
|
||||
public FadvisedFileRegion(RandomAccessFile file, long position, long count,
|
||||
boolean manageOsCache, int readaheadLength, ReadaheadPool readaheadPool,
|
||||
@ -74,6 +75,8 @@ public FadvisedFileRegion(RandomAccessFile file, long position, long count,
|
||||
@Override
|
||||
public long transferTo(WritableByteChannel target, long position)
|
||||
throws IOException {
|
||||
synchronized (closeLock) {
|
||||
if (fd.valid()) {
|
||||
if (readaheadPool != null && readaheadLength > 0) {
|
||||
readaheadRequest = readaheadPool.readaheadStream(identifier, fd,
|
||||
position() + position, readaheadLength,
|
||||
@ -85,6 +88,11 @@ public long transferTo(WritableByteChannel target, long position)
|
||||
} else {
|
||||
return customShuffleTransfer(target, position);
|
||||
}
|
||||
} else {
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -147,23 +155,29 @@ long customShuffleTransfer(WritableByteChannel target, long position)
|
||||
|
||||
@Override
|
||||
protected void deallocate() {
|
||||
synchronized (closeLock) {
|
||||
if (readaheadRequest != null) {
|
||||
readaheadRequest.cancel();
|
||||
readaheadRequest = null;
|
||||
}
|
||||
super.deallocate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call when the transfer completes successfully so we can advise the OS that
|
||||
* we don't need the region to be cached anymore.
|
||||
*/
|
||||
public void transferSuccessful() {
|
||||
if (manageOsCache && count() > 0) {
|
||||
synchronized (closeLock) {
|
||||
if (fd.valid() && manageOsCache && count() > 0) {
|
||||
try {
|
||||
NativeIO.POSIX.getCacheManipulator().posixFadviseIfPossible(identifier,
|
||||
fd, position(), count(), POSIX_FADV_DONTNEED);
|
||||
} catch (Throwable t) {
|
||||
LOG.warn("Failed to manage OS cache for " + identifier, t);
|
||||
LOG.warn("Failed to manage OS cache for " + identifier +
|
||||
" fd " + fd, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user