mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-06 00:25:25 +02:00
192437: apply fix
This commit is contained in:
parent
4f3484f3e7
commit
3fdfd1e46b
7 changed files with 81 additions and 12 deletions
|
@ -52,7 +52,7 @@ public class BTreeTests extends BaseTestCase {
|
|||
// and invoke it multiple times per Junit test
|
||||
protected void init(int degree) throws Exception {
|
||||
dbFile = File.createTempFile("pdomtest", "db");
|
||||
db = new Database(dbFile, new ChunkCache(), 0);
|
||||
db = new Database(dbFile, new ChunkCache(), 0, false);
|
||||
db.setWritable();
|
||||
rootRecord = Database.DATA_AREA;
|
||||
comparator = new BTMockRecordComparator();
|
||||
|
|
|
@ -37,7 +37,7 @@ public class DBPropertiesTests extends BaseTestCase {
|
|||
protected void setUp() throws Exception {
|
||||
dbLoc = File.createTempFile("test", "db");
|
||||
dbLoc.deleteOnExit();
|
||||
db = new Database(dbLoc, new ChunkCache(), 0);
|
||||
db = new Database(dbLoc, new ChunkCache(), 0, false);
|
||||
db.setWritable();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
package org.eclipse.cdt.internal.pdom.tests;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Random;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
@ -35,7 +36,7 @@ public class DBTest extends BaseTestCase {
|
|||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
db = new Database(getTestDir().append(getName()+System.currentTimeMillis()+".dat").toFile(),
|
||||
new ChunkCache(), 0);
|
||||
new ChunkCache(), 0, false);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
|
@ -73,6 +74,30 @@ public class DBTest extends BaseTestCase {
|
|||
assertEquals(mem - Database.INT_SIZE + blocksize, db.getInt(((Database.CHUNK_SIZE - blocksize) / Database.MIN_SIZE) * Database.INT_SIZE));
|
||||
}
|
||||
|
||||
public void testBug192437() throws IOException {
|
||||
File tmp= File.createTempFile("readOnlyEmpty", ".db");
|
||||
try {
|
||||
tmp.setReadOnly();
|
||||
|
||||
/* check opening a readonly file for rw access fails */
|
||||
try {
|
||||
new Database(tmp, ChunkCache.getSharedInstance(), 0, false);
|
||||
fail("A readonly file should not be openable with write-access");
|
||||
} catch(CoreException ioe) {
|
||||
// we expect to get a failure here
|
||||
}
|
||||
|
||||
/* check opening a readonly file for read access does not fail */
|
||||
try {
|
||||
new Database(tmp, ChunkCache.getSharedInstance(), 0, true);
|
||||
} catch(CoreException ce) {
|
||||
fail("A readonly file should be readable by a permanently readonly database "+ce);
|
||||
}
|
||||
} finally {
|
||||
tmp.delete(); // this may be pointless on some platforms
|
||||
}
|
||||
}
|
||||
|
||||
public void testFreeBlockLinking() throws Exception {
|
||||
final int realsize = 42;
|
||||
final int blocksize = (realsize / Database.MIN_SIZE + 1) * Database.MIN_SIZE;
|
||||
|
@ -126,7 +151,7 @@ public class DBTest extends BaseTestCase {
|
|||
// Tests inserting and retrieving strings
|
||||
File f = getTestDir().append("testStrings.dat").toFile();
|
||||
f.delete();
|
||||
final Database db = new Database(f, new ChunkCache(), 0);
|
||||
final Database db = new Database(f, new ChunkCache(), 0, false);
|
||||
db.setWritable();
|
||||
|
||||
String[] names = {
|
||||
|
|
|
@ -165,7 +165,7 @@ public class PDOMCPPBugsTest extends BaseTestCase {
|
|||
}
|
||||
|
||||
public void testInterruptingAcquireWriteLock() throws Exception {
|
||||
final PDOM pdom= (PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject);
|
||||
final WritablePDOM pdom= (WritablePDOM) CCoreInternals.getPDOMManager().getPDOM(cproject);
|
||||
final boolean[] ok= {false};
|
||||
pdom.acquireReadLock();
|
||||
try {
|
||||
|
|
|
@ -135,9 +135,16 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
|
|||
this.locationConverter = locationConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this PDOM can never be written to. Writable subclasses should return false.
|
||||
*/
|
||||
protected boolean isPermanentlyReadOnly() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void loadDatabase(File dbPath, ChunkCache cache) throws CoreException {
|
||||
fPath= dbPath;
|
||||
db = new Database(fPath, cache, VERSION);
|
||||
db = new Database(fPath, cache, VERSION, isPermanentlyReadOnly());
|
||||
fileIndex= null; // holds on to the database, so clear it.
|
||||
|
||||
int version= db.getVersion();
|
||||
|
@ -258,7 +265,9 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
|
|||
CCorePlugin.log(e);
|
||||
}
|
||||
loadDatabase(file, db.getChunkCache());
|
||||
db.setWritable();
|
||||
if(!isPermanentlyReadOnly()) {
|
||||
db.setWritable();
|
||||
}
|
||||
oldFile.delete();
|
||||
}
|
||||
|
||||
|
@ -549,10 +558,21 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire a write lock on this PDOM. Blocks until any existing read/write locks are released.
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalStateException if this PDOM is not writable
|
||||
*/
|
||||
public void acquireWriteLock() throws InterruptedException {
|
||||
acquireWriteLock(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire a write lock on this PDOM, giving up the specified number of read locks first. Blocks
|
||||
* until any existing read/write locks are released.
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalStateException if this PDOM is not writable
|
||||
*/
|
||||
public void acquireWriteLock(int giveupReadLocks) throws InterruptedException {
|
||||
synchronized (mutex) {
|
||||
if (giveupReadLocks > 0) {
|
||||
|
|
|
@ -154,4 +154,8 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
|||
void setCreatedFromScratch(boolean createdFromScratch) {
|
||||
fCreatedFromScratch = createdFromScratch;
|
||||
}
|
||||
|
||||
protected final boolean isPermanentlyReadOnly() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ public class Database {
|
|||
private final File location;
|
||||
private final RandomAccessFile file;
|
||||
private boolean fWritable= false;
|
||||
private boolean fPermanentlyReadOnly;
|
||||
private Chunk[] chunks;
|
||||
|
||||
private long malloced;
|
||||
|
@ -82,17 +83,28 @@ public class Database {
|
|||
|
||||
public static final int MAX_SIZE = CHUNK_SIZE - 4; // Room for overhead
|
||||
|
||||
public Database(File location, ChunkCache cache, int version) throws CoreException {
|
||||
/**
|
||||
* Construct a new Database object, creating a backing file if necessary.
|
||||
* @param location the local file path for the database
|
||||
* @param cache the cache to be used optimisation
|
||||
* @param version the version number to store in the database (only applicable for new databases)
|
||||
* @param permanentReadOnly whether this Database object will ever need writing to
|
||||
* @throws CoreException
|
||||
*/
|
||||
public Database(File location, ChunkCache cache, int version, boolean permanentlyReadOnly) throws CoreException {
|
||||
try {
|
||||
this.location = location;
|
||||
this.file = new RandomAccessFile(location, "rw"); //$NON-NLS-1$
|
||||
fCache= cache;
|
||||
this.fPermanentlyReadOnly= permanentlyReadOnly;
|
||||
this.file = new RandomAccessFile(location, permanentlyReadOnly ? "r" : "rw"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
this.fCache= cache;
|
||||
|
||||
// Allocate chunk table, make sure we have at least one
|
||||
long nChunks = file.length() / CHUNK_SIZE;
|
||||
chunks = new Chunk[(int)nChunks];
|
||||
if (nChunks == 0) {
|
||||
setWritable();
|
||||
if(!permanentlyReadOnly) {
|
||||
setWritable();
|
||||
}
|
||||
createNewChunk();
|
||||
setVersion(version);
|
||||
setReadOnly(true);
|
||||
|
@ -428,7 +440,15 @@ public class Database {
|
|||
return fCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks this Database as writable. This is used for avoiding some synchronization on chunk fetching. An
|
||||
* exception is thrown if this Database was constructed as a permanently read only Database.
|
||||
* @see Database#Database(File, ChunkCache, int, boolean)
|
||||
* @throw IllegalStateException if called on a permanently read-only database
|
||||
*/
|
||||
public void setWritable() {
|
||||
if(fPermanentlyReadOnly)
|
||||
throw new IllegalStateException("A Database created as permanent-read-only may not be changed to writable state"); //$NON-NLS-1$
|
||||
fWritable= true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue