Made sure that all access to sectorFree is moved to inside the protected area as well.

This commit is contained in:
Fredrik Blom 2012-11-15 16:02:36 +01:00
parent 6326bdac82
commit 258eff946b

View file

@ -26,6 +26,7 @@ namespace Substrate.Core
/// The file lock used so that we do not seek in different areas /// The file lock used so that we do not seek in different areas
/// of the same file at the same time. All file access should lock this /// of the same file at the same time. All file access should lock this
/// object before moving the file pointer. /// object before moving the file pointer.
/// The lock should also surround all access to the sectorFree free variable.
/// </summary> /// </summary>
private object fileLock = new object(); private object fileLock = new object();
@ -245,12 +246,13 @@ namespace Substrate.Core
int sectorNumber = offset >> 8; int sectorNumber = offset >> 8;
int numSectors = offset & 0xFF; int numSectors = offset & 0xFF;
if (sectorNumber + numSectors > sectorFree.Count) { lock (this.fileLock)
Debugln("READ", x, z, "invalid sector"); {
return null; if (sectorNumber + numSectors > sectorFree.Count) {
} Debugln("READ", x, z, "invalid sector");
return null;
}
lock (this.fileLock) {
file.Seek(sectorNumber * SectorBytes, SeekOrigin.Begin); file.Seek(sectorNumber * SectorBytes, SeekOrigin.Begin);
byte[] lengthBytes = new byte[4]; byte[] lengthBytes = new byte[4];
file.Read(lengthBytes, 0, 4); file.Read(lengthBytes, 0, 4);
@ -381,46 +383,46 @@ namespace Substrate.Core
else { else {
/* we need to allocate new sectors */ /* we need to allocate new sectors */
/* mark the sectors previously used for this chunk as free */ lock (this.fileLock) {
for (int i = 0; i < sectorsAllocated; ++i) { /* mark the sectors previously used for this chunk as free */
sectorFree[sectorNumber + i] = true; for (int i = 0; i < sectorsAllocated; ++i) {
} sectorFree[sectorNumber + i] = true;
}
/* scan for a free space large enough to store this chunk */ /* scan for a free space large enough to store this chunk */
int runStart = sectorFree.FindIndex(b => b == true); int runStart = sectorFree.FindIndex(b => b == true);
int runLength = 0; int runLength = 0;
if (runStart != -1) { if (runStart != -1) {
for (int i = runStart; i < sectorFree.Count; ++i) { for (int i = runStart; i < sectorFree.Count; ++i) {
if (runLength != 0) { if (runLength != 0) {
if (sectorFree[i]) runLength++; if (sectorFree[i]) runLength++;
else runLength = 0; else runLength = 0;
} }
else if (sectorFree[i]) { else if (sectorFree[i]) {
runStart = i; runStart = i;
runLength = 1; runLength = 1;
} }
if (runLength >= sectorsNeeded) { if (runLength >= sectorsNeeded) {
break; break;
}
} }
} }
}
if (runLength >= sectorsNeeded) { if (runLength >= sectorsNeeded) {
/* we found a free space large enough */ /* we found a free space large enough */
Debug("SAVE", x, z, length, "reuse"); Debug("SAVE", x, z, length, "reuse");
sectorNumber = runStart; sectorNumber = runStart;
SetOffset(x, z, (sectorNumber << 8) | sectorsNeeded); SetOffset(x, z, (sectorNumber << 8) | sectorsNeeded);
for (int i = 0; i < sectorsNeeded; ++i) { for (int i = 0; i < sectorsNeeded; ++i) {
sectorFree[sectorNumber + i] = false; sectorFree[sectorNumber + i] = false;
}
Write(sectorNumber, data, length);
} }
Write(sectorNumber, data, length); else {
} /*
else { * no free space large enough found -- we need to grow the
/* * file
* no free space large enough found -- we need to grow the */
* file
*/
lock (this.fileLock) {
Debug("SAVE", x, z, length, "grow"); Debug("SAVE", x, z, length, "grow");
file.Seek(0, SeekOrigin.End); file.Seek(0, SeekOrigin.End);
sectorNumber = sectorFree.Count; sectorNumber = sectorFree.Count;