Introduce InputFile/OutputFile and FileMutex.
FileHandle is replaced with InputFile/OutputFile and FileMutex.
Use InputFile when you want to open a file in read-only.
USe OutputFile when you open a file for writing.
Both of them provide a reliable way to access the files and perform
the I/O operations.
Given a name "foo", FileMutex creates a file named "foo.lock" and
tries to acquire an advisory lock (flock) on this file.
FileHandle, which uses the file it's openning for locking, may corrupt
the file contents when two or more processes are trying to gain the
lock for reading/writing. For example:
Process #2 creates foo
Process #1 opens foo
Process #2 opens foo
Process #2 locks foo (exclusively) (success)
Process #1 locks foo (failed, retry #1)
Process #2 starts writing foo
Process #1 opens and truncates foo (note there’s O_TRUNC in the flag)
Process #2 writes foo continually (foo is corrupted from now on ...)
Process #1 locks foo (failed, retry #2)
...
Process #1 locks foo (reach the max retries and return)
Process #2 gets done on writing foo (foo is corrupted ...)
Process #2 unlocks and closes foo (foo is corrupted)
Change-Id: If416383717cc692741e59ff1e387adf90546e36f
diff --git a/lib/ExecutionEngine/MCCacheReader.cpp b/lib/ExecutionEngine/MCCacheReader.cpp
index bf4fe47..0a70ff6 100644
--- a/lib/ExecutionEngine/MCCacheReader.cpp
+++ b/lib/ExecutionEngine/MCCacheReader.cpp
@@ -17,7 +17,7 @@
#include "MCCacheReader.h"
#include "DebugHelper.h"
-#include "FileHandle.h"
+#include "InputFile.h"
#include "ScriptCached.h"
#include "Runtime.h"
@@ -49,8 +49,8 @@
if (mpFuncNameList) { free(mpFuncNameList); }
}
-ScriptCached *MCCacheReader::readCacheFile(FileHandle *objFile,
- FileHandle *infoFile,
+ScriptCached *MCCacheReader::readCacheFile(InputFile &objFile,
+ InputFile &infoFile,
Script *S) {
bool result = checkCacheFile(objFile, infoFile, S)
&& readPragmaList()
@@ -65,16 +65,16 @@
return result ? mpResult.take() : NULL;
}
-bool MCCacheReader::checkCacheFile(FileHandle *objFile,
- FileHandle *infoFile,
- Script *S) {
+bool MCCacheReader::checkCacheFile(InputFile &objFile,
+ InputFile &infoFile,
+ Script *S) {
// Check file handle
- if (!objFile || objFile->getFD() < 0 || !infoFile || infoFile->getFD() < 0) {
+ if (objFile.hasError() || infoFile.hasError()) {
return false;
}
- mObjFile = objFile;
- mInfoFile = infoFile;
+ mObjFile = &objFile;
+ mInfoFile = &infoFile;
// Allocate ScriptCached object
mpResult.reset(new (nothrow) ScriptCached(S));
@@ -101,7 +101,7 @@
bool MCCacheReader::checkFileSize() {
struct stat stfile;
- if (fstat(mInfoFile->getFD(), &stfile) < 0) {
+ if (::stat(mInfoFile->getName().c_str(), &stfile) < 0) {
ALOGE("Unable to stat cache file.\n");
return false;
}
@@ -118,7 +118,7 @@
bool MCCacheReader::readHeader() {
- if (mInfoFile->seek(0, SEEK_SET) != 0) {
+ if (mInfoFile->seek(0) != 0) {
ALOGE("Unable to seek to 0. (reason: %s)\n", strerror(errno));
return false;
}
@@ -226,7 +226,7 @@
/* We have to ensure that some one will deallocate NAME##_raw */ \
AUTO_MANAGED_HOLDER = NAME##_raw; \
\
- if (mInfoFile->seek(mpHeader->NAME##_offset, SEEK_SET) == -1) { \
+ if (mInfoFile->seek(mpHeader->NAME##_offset) == -1) { \
ALOGE("Unable to seek to " #NAME " section\n"); \
return false; \
} \