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 =
|
private static final Logger LOG =
|
||||||
LoggerFactory.getLogger(FadvisedFileRegion.class);
|
LoggerFactory.getLogger(FadvisedFileRegion.class);
|
||||||
|
|
||||||
|
private final Object closeLock = new Object();
|
||||||
private final boolean manageOsCache;
|
private final boolean manageOsCache;
|
||||||
private final int readaheadLength;
|
private final int readaheadLength;
|
||||||
private final ReadaheadPool readaheadPool;
|
private final ReadaheadPool readaheadPool;
|
||||||
@ -52,7 +53,7 @@ public class FadvisedFileRegion extends DefaultFileRegion {
|
|||||||
private final boolean shuffleTransferToAllowed;
|
private final boolean shuffleTransferToAllowed;
|
||||||
private final FileChannel fileChannel;
|
private final FileChannel fileChannel;
|
||||||
|
|
||||||
private ReadaheadRequest readaheadRequest;
|
private volatile ReadaheadRequest readaheadRequest;
|
||||||
|
|
||||||
public FadvisedFileRegion(RandomAccessFile file, long position, long count,
|
public FadvisedFileRegion(RandomAccessFile file, long position, long count,
|
||||||
boolean manageOsCache, int readaheadLength, ReadaheadPool readaheadPool,
|
boolean manageOsCache, int readaheadLength, ReadaheadPool readaheadPool,
|
||||||
@ -74,6 +75,8 @@ public FadvisedFileRegion(RandomAccessFile file, long position, long count,
|
|||||||
@Override
|
@Override
|
||||||
public long transferTo(WritableByteChannel target, long position)
|
public long transferTo(WritableByteChannel target, long position)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
synchronized (closeLock) {
|
||||||
|
if (fd.valid()) {
|
||||||
if (readaheadPool != null && readaheadLength > 0) {
|
if (readaheadPool != null && readaheadLength > 0) {
|
||||||
readaheadRequest = readaheadPool.readaheadStream(identifier, fd,
|
readaheadRequest = readaheadPool.readaheadStream(identifier, fd,
|
||||||
position() + position, readaheadLength,
|
position() + position, readaheadLength,
|
||||||
@ -85,6 +88,11 @@ public long transferTo(WritableByteChannel target, long position)
|
|||||||
} else {
|
} else {
|
||||||
return customShuffleTransfer(target, position);
|
return customShuffleTransfer(target, position);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,23 +155,29 @@ long customShuffleTransfer(WritableByteChannel target, long position)
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void deallocate() {
|
protected void deallocate() {
|
||||||
|
synchronized (closeLock) {
|
||||||
if (readaheadRequest != null) {
|
if (readaheadRequest != null) {
|
||||||
readaheadRequest.cancel();
|
readaheadRequest.cancel();
|
||||||
|
readaheadRequest = null;
|
||||||
}
|
}
|
||||||
super.deallocate();
|
super.deallocate();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call when the transfer completes successfully so we can advise the OS that
|
* Call when the transfer completes successfully so we can advise the OS that
|
||||||
* we don't need the region to be cached anymore.
|
* we don't need the region to be cached anymore.
|
||||||
*/
|
*/
|
||||||
public void transferSuccessful() {
|
public void transferSuccessful() {
|
||||||
if (manageOsCache && count() > 0) {
|
synchronized (closeLock) {
|
||||||
|
if (fd.valid() && manageOsCache && count() > 0) {
|
||||||
try {
|
try {
|
||||||
NativeIO.POSIX.getCacheManipulator().posixFadviseIfPossible(identifier,
|
NativeIO.POSIX.getCacheManipulator().posixFadviseIfPossible(identifier,
|
||||||
fd, position(), count(), POSIX_FADV_DONTNEED);
|
fd, position(), count(), POSIX_FADV_DONTNEED);
|
||||||
} catch (Throwable t) {
|
} 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