mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Fix for ClosedChannelException when accessing the PDOM, bug 219834.
This commit is contained in:
parent
5f9327914d
commit
e47f872406
1 changed files with 42 additions and 4 deletions
|
@ -14,9 +14,12 @@
|
||||||
package org.eclipse.cdt.internal.core.pdom.db;
|
package org.eclipse.cdt.internal.core.pdom.db;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.ClosedByInterruptException;
|
||||||
|
import java.nio.channels.ClosedChannelException;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -75,7 +78,8 @@ public class Database {
|
||||||
private static final int BLOCK_NEXT_OFFSET = BLOCK_HEADER_SIZE + INT_SIZE;
|
private static final int BLOCK_NEXT_OFFSET = BLOCK_HEADER_SIZE + INT_SIZE;
|
||||||
|
|
||||||
private final File fLocation;
|
private final File fLocation;
|
||||||
private final RandomAccessFile fFile;
|
private final boolean fReadOnly;
|
||||||
|
private RandomAccessFile fFile;
|
||||||
private boolean fExclusiveLock= false; // necessary for any write operation
|
private boolean fExclusiveLock= false; // necessary for any write operation
|
||||||
private boolean fLocked; // necessary for any operation.
|
private boolean fLocked; // necessary for any operation.
|
||||||
private boolean fIsMarkedIncomplete= false;
|
private boolean fIsMarkedIncomplete= false;
|
||||||
|
@ -101,8 +105,9 @@ public class Database {
|
||||||
public Database(File location, ChunkCache cache, int version, boolean openReadOnly) throws CoreException {
|
public Database(File location, ChunkCache cache, int version, boolean openReadOnly) throws CoreException {
|
||||||
try {
|
try {
|
||||||
fLocation = location;
|
fLocation = location;
|
||||||
fFile = new RandomAccessFile(location, openReadOnly ? "r" : "rw"); //$NON-NLS-1$ //$NON-NLS-2$
|
fReadOnly= openReadOnly;
|
||||||
fCache= cache;
|
fCache= cache;
|
||||||
|
openFile();
|
||||||
|
|
||||||
int nChunksOnDisk = (int) (fFile.length() / CHUNK_SIZE);
|
int nChunksOnDisk = (int) (fFile.length() / CHUNK_SIZE);
|
||||||
fHeaderChunk= new Chunk(this, 0);
|
fHeaderChunk= new Chunk(this, 0);
|
||||||
|
@ -121,13 +126,46 @@ public class Database {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void openFile() throws FileNotFoundException {
|
||||||
|
fFile = new RandomAccessFile(fLocation, fReadOnly ? "r" : "rw"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
|
||||||
void read(ByteBuffer buf, int i) throws IOException {
|
void read(ByteBuffer buf, int i) throws IOException {
|
||||||
|
int retries= 0;
|
||||||
|
do {
|
||||||
|
try {
|
||||||
fFile.getChannel().read(buf, i);
|
fFile.getChannel().read(buf, i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (ClosedChannelException e) {
|
||||||
|
// bug 219834 file may have be closed by interrupting a thread during an I/O operation.
|
||||||
|
reopen(e, ++retries);
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(ByteBuffer buf, int i) throws IOException {
|
void write(ByteBuffer buf, int i) throws IOException {
|
||||||
|
int retries= 0;
|
||||||
|
do {
|
||||||
|
try {
|
||||||
fFile.getChannel().write(buf, i);
|
fFile.getChannel().write(buf, i);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
catch (ClosedChannelException e) {
|
||||||
|
// bug 219834 file may have be closed by interrupting a thread during an I/O operation.
|
||||||
|
reopen(e, ++retries);
|
||||||
|
}
|
||||||
|
} while(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reopen(ClosedChannelException e, int attempt) throws ClosedChannelException, FileNotFoundException {
|
||||||
|
// only if the current thread was not interrupted we try to reopen the file.
|
||||||
|
if (e instanceof ClosedByInterruptException || attempt >= 20) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
openFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void transferTo(FileChannel target) throws IOException {
|
public void transferTo(FileChannel target) throws IOException {
|
||||||
assert fLocked;
|
assert fLocked;
|
||||||
|
|
Loading…
Add table
Reference in a new issue