Merge "ScopedFlock: Refactor it to be a subclass of FdFile."
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index d5d927c..f9267e2 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -2169,30 +2169,27 @@
// cleaning up before that (e.g. the oat writers are created before the
// runtime).
profile_compilation_info_.reset(new ProfileCompilationInfo());
- ScopedFlock flock;
- bool success = true;
+ ScopedFlock profile_file;
std::string error;
if (profile_file_fd_ != -1) {
- // The file doesn't need to be flushed so don't check the usage.
- // Pass a bogus path so that we can easily attribute any reported error.
- File file(profile_file_fd_, "profile", /*check_usage*/ false, /*read_only_mode*/ true);
- if (flock.Init(&file, &error)) {
- success = profile_compilation_info_->Load(profile_file_fd_);
- }
+ profile_file = LockedFile::DupOf(profile_file_fd_, "profile",
+ true /* read_only_mode */, &error);
} else if (profile_file_ != "") {
- if (flock.Init(profile_file_.c_str(), O_RDONLY, /* block */ true, &error)) {
- success = profile_compilation_info_->Load(flock.GetFile()->Fd());
- }
- }
- if (!error.empty()) {
- LOG(WARNING) << "Cannot lock profiles: " << error;
+ profile_file = LockedFile::Open(profile_file_.c_str(), O_RDONLY, true, &error);
}
- if (!success) {
+ // Return early if we're unable to obtain a lock on the profile.
+ if (profile_file.get() == nullptr) {
+ LOG(ERROR) << "Cannot lock profiles: " << error;
+ return false;
+ }
+
+ if (!profile_compilation_info_->Load(profile_file->Fd())) {
profile_compilation_info_.reset(nullptr);
+ return false;
}
- return success;
+ return true;
}
private:
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index ec3481b..848eb8d 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -304,8 +304,10 @@
TimingLogger::ScopedTiming t("Writing image File", timings_);
std::string error_msg;
- ScopedFlock img_flock;
- img_flock.Init(out, &error_msg);
+ // No error checking here, this is best effort. The locking may or may not
+ // succeed and we don't really care either way.
+ ScopedFlock img_flock = LockedFile::DupOf(out->Fd(), out->GetPath(),
+ true /* read_only_mode */, &error_msg);
CHECK(image_ != nullptr);
CHECK(out != nullptr);
diff --git a/profman/profile_assistant.cc b/profman/profile_assistant.cc
index b9a85bc..c238f0d 100644
--- a/profman/profile_assistant.cc
+++ b/profman/profile_assistant.cc
@@ -33,7 +33,7 @@
ProfileCompilationInfo info;
// Load the reference profile.
- if (!info.Load(reference_profile_file.GetFile()->Fd())) {
+ if (!info.Load(reference_profile_file->Fd())) {
LOG(WARNING) << "Could not load reference profile file";
return kErrorBadProfiles;
}
@@ -45,7 +45,7 @@
// Merge all current profiles.
for (size_t i = 0; i < profile_files.size(); i++) {
ProfileCompilationInfo cur_info;
- if (!cur_info.Load(profile_files[i].GetFile()->Fd())) {
+ if (!cur_info.Load(profile_files[i]->Fd())) {
LOG(WARNING) << "Could not load profile file at index " << i;
return kErrorBadProfiles;
}
@@ -62,11 +62,11 @@
}
// We were successful in merging all profile information. Update the reference profile.
- if (!reference_profile_file.GetFile()->ClearContent()) {
+ if (!reference_profile_file->ClearContent()) {
PLOG(WARNING) << "Could not clear reference profile file";
return kErrorIO;
}
- if (!info.Save(reference_profile_file.GetFile()->Fd())) {
+ if (!info.Save(reference_profile_file->Fd())) {
LOG(WARNING) << "Could not save reference profile file";
return kErrorIO;
}
@@ -74,26 +74,15 @@
return kCompile;
}
-static bool InitFlock(const std::string& filename, ScopedFlock& flock, std::string* error) {
- return flock.Init(filename.c_str(), O_RDWR, /* block */ true, error);
-}
-
-static bool InitFlock(int fd, ScopedFlock& flock, std::string* error) {
- DCHECK_GE(fd, 0);
- // We do not own the descriptor, so disable auto-close and don't check usage.
- File file(fd, false);
- file.DisableAutoClose();
- return flock.Init(&file, error);
-}
-
-class ScopedCollectionFlock {
+class ScopedFlockList {
public:
- explicit ScopedCollectionFlock(size_t size) : flocks_(size) {}
+ explicit ScopedFlockList(size_t size) : flocks_(size) {}
// Will block until all the locks are acquired.
bool Init(const std::vector<std::string>& filenames, /* out */ std::string* error) {
for (size_t i = 0; i < filenames.size(); i++) {
- if (!InitFlock(filenames[i], flocks_[i], error)) {
+ flocks_[i] = LockedFile::Open(filenames[i].c_str(), O_RDWR, /* block */ true, error);
+ if (flocks_[i].get() == nullptr) {
*error += " (index=" + std::to_string(i) + ")";
return false;
}
@@ -105,7 +94,9 @@
bool Init(const std::vector<int>& fds, /* out */ std::string* error) {
for (size_t i = 0; i < fds.size(); i++) {
DCHECK_GE(fds[i], 0);
- if (!InitFlock(fds[i], flocks_[i], error)) {
+ flocks_[i] = LockedFile::DupOf(fds[i], "profile-file",
+ true /* read_only_mode */, error);
+ if (flocks_[i].get() == nullptr) {
*error += " (index=" + std::to_string(i) + ")";
return false;
}
@@ -123,39 +114,47 @@
const std::vector<int>& profile_files_fd,
int reference_profile_file_fd) {
DCHECK_GE(reference_profile_file_fd, 0);
+
std::string error;
- ScopedCollectionFlock profile_files_flocks(profile_files_fd.size());
- if (!profile_files_flocks.Init(profile_files_fd, &error)) {
+ ScopedFlockList profile_files(profile_files_fd.size());
+ if (!profile_files.Init(profile_files_fd, &error)) {
LOG(WARNING) << "Could not lock profile files: " << error;
return kErrorCannotLock;
}
- ScopedFlock reference_profile_file_flock;
- if (!InitFlock(reference_profile_file_fd, reference_profile_file_flock, &error)) {
+
+ // The reference_profile_file is opened in read/write mode because it's
+ // cleared after processing.
+ ScopedFlock reference_profile_file = LockedFile::DupOf(reference_profile_file_fd,
+ "reference-profile",
+ false /* read_only_mode */,
+ &error);
+ if (reference_profile_file.get() == nullptr) {
LOG(WARNING) << "Could not lock reference profiled files: " << error;
return kErrorCannotLock;
}
- return ProcessProfilesInternal(profile_files_flocks.Get(),
- reference_profile_file_flock);
+ return ProcessProfilesInternal(profile_files.Get(), reference_profile_file);
}
ProfileAssistant::ProcessingResult ProfileAssistant::ProcessProfiles(
const std::vector<std::string>& profile_files,
const std::string& reference_profile_file) {
std::string error;
- ScopedCollectionFlock profile_files_flocks(profile_files.size());
- if (!profile_files_flocks.Init(profile_files, &error)) {
+
+ ScopedFlockList profile_files_list(profile_files.size());
+ if (!profile_files_list.Init(profile_files, &error)) {
LOG(WARNING) << "Could not lock profile files: " << error;
return kErrorCannotLock;
}
- ScopedFlock reference_profile_file_flock;
- if (!InitFlock(reference_profile_file, reference_profile_file_flock, &error)) {
+
+ ScopedFlock locked_reference_profile_file = LockedFile::Open(
+ reference_profile_file.c_str(), O_RDWR, /* block */ true, &error);
+ if (locked_reference_profile_file.get() == nullptr) {
LOG(WARNING) << "Could not lock reference profile files: " << error;
return kErrorCannotLock;
}
- return ProcessProfilesInternal(profile_files_flocks.Get(),
- reference_profile_file_flock);
+ return ProcessProfilesInternal(profile_files_list.Get(), locked_reference_profile_file);
}
} // namespace art
diff --git a/runtime/base/scoped_flock.cc b/runtime/base/scoped_flock.cc
index 862f0d0..b8df689 100644
--- a/runtime/base/scoped_flock.cc
+++ b/runtime/base/scoped_flock.cc
@@ -28,46 +28,39 @@
using android::base::StringPrintf;
-bool ScopedFlock::Init(const char* filename, std::string* error_msg) {
- return Init(filename, O_CREAT | O_RDWR, true, error_msg);
+/* static */ ScopedFlock LockedFile::Open(const char* filename, std::string* error_msg) {
+ return Open(filename, O_CREAT | O_RDWR, true, error_msg);
}
-bool ScopedFlock::Init(const char* filename, int flags, bool block, std::string* error_msg) {
- return Init(filename, flags, block, true, error_msg);
-}
-
-bool ScopedFlock::Init(const char* filename,
- int flags,
- bool block,
- bool flush_on_close,
- std::string* error_msg) {
- flush_on_close_ = flush_on_close;
+/* static */ ScopedFlock LockedFile::Open(const char* filename, int flags, bool block,
+ std::string* error_msg) {
while (true) {
- if (file_.get() != nullptr) {
- UNUSED(file_->FlushCloseOrErase()); // Ignore result.
+ // NOTE: We don't check usage here because the ScopedFlock should *never* be
+ // responsible for flushing its underlying FD. Its only purpose should be
+ // to acquire a lock, and the unlock / close in the corresponding
+ // destructor. Callers should explicitly flush files they're writing to if
+ // that is the desired behaviour.
+ std::unique_ptr<File> file(OS::OpenFileWithFlags(filename, flags, false /* check_usage */));
+ if (file.get() == nullptr) {
+ *error_msg = StringPrintf("Failed to open file '%s': %s", filename, strerror(errno));
+ return nullptr;
}
- bool check_usage = flush_on_close; // Check usage only if we need to flush on close.
- file_.reset(OS::OpenFileWithFlags(filename, flags, check_usage));
- if (file_.get() == nullptr) {
- *error_msg = StringPrintf("Failed to open file '%s': %s", filename, strerror(errno));
- return false;
- }
int operation = block ? LOCK_EX : (LOCK_EX | LOCK_NB);
- int flock_result = TEMP_FAILURE_RETRY(flock(file_->Fd(), operation));
+ int flock_result = TEMP_FAILURE_RETRY(flock(file->Fd(), operation));
if (flock_result == EWOULDBLOCK) {
// File is locked by someone else and we are required not to block;
- return false;
+ return nullptr;
}
if (flock_result != 0) {
*error_msg = StringPrintf("Failed to lock file '%s': %s", filename, strerror(errno));
- return false;
+ return nullptr;
}
struct stat fstat_stat;
- int fstat_result = TEMP_FAILURE_RETRY(fstat(file_->Fd(), &fstat_stat));
+ int fstat_result = TEMP_FAILURE_RETRY(fstat(file->Fd(), &fstat_stat));
if (fstat_result != 0) {
*error_msg = StringPrintf("Failed to fstat file '%s': %s", filename, strerror(errno));
- return false;
+ return nullptr;
}
struct stat stat_stat;
int stat_result = TEMP_FAILURE_RETRY(stat(filename, &stat_stat));
@@ -80,7 +73,7 @@
// Note that in theory we could race with someone here for a long time and end up retrying
// over and over again. This potential behavior does not fit well in the non-blocking
// semantics. Thus, if we are not require to block return failure when racing.
- return false;
+ return nullptr;
}
}
if (fstat_stat.st_dev != stat_stat.st_dev || fstat_stat.st_ino != stat_stat.st_ino) {
@@ -89,61 +82,47 @@
continue;
} else {
// See comment above.
- return false;
+ return nullptr;
}
}
- return true;
+
+ return ScopedFlock(new LockedFile(std::move((*file.get()))));
}
}
-bool ScopedFlock::Init(File* file, std::string* error_msg) {
- flush_on_close_ = true;
- file_.reset(new File(dup(file->Fd()), file->GetPath(), file->CheckUsage(), file->ReadOnlyMode()));
- if (file_->Fd() == -1) {
- file_.reset();
+ScopedFlock LockedFile::DupOf(const int fd, const std::string& path,
+ const bool read_only_mode, std::string* error_msg) {
+ // NOTE: We don't check usage here because the ScopedFlock should *never* be
+ // responsible for flushing its underlying FD. Its only purpose should be
+ // to acquire a lock, and the unlock / close in the corresponding
+ // destructor. Callers should explicitly flush files they're writing to if
+ // that is the desired behaviour.
+ ScopedFlock locked_file(
+ new LockedFile(dup(fd), path, false /* check_usage */, read_only_mode));
+ if (locked_file->Fd() == -1) {
*error_msg = StringPrintf("Failed to duplicate open file '%s': %s",
- file->GetPath().c_str(), strerror(errno));
- return false;
+ locked_file->GetPath().c_str(), strerror(errno));
+ return nullptr;
}
- if (0 != TEMP_FAILURE_RETRY(flock(file_->Fd(), LOCK_EX))) {
- file_.reset();
+ if (0 != TEMP_FAILURE_RETRY(flock(locked_file->Fd(), LOCK_EX))) {
*error_msg = StringPrintf(
- "Failed to lock file '%s': %s", file->GetPath().c_str(), strerror(errno));
- return false;
+ "Failed to lock file '%s': %s", locked_file->GetPath().c_str(), strerror(errno));
+ return nullptr;
}
- return true;
+
+ return locked_file;
}
-File* ScopedFlock::GetFile() const {
- CHECK(file_.get() != nullptr);
- return file_.get();
-}
-
-bool ScopedFlock::HasFile() {
- return file_.get() != nullptr;
-}
-
-ScopedFlock::ScopedFlock() : flush_on_close_(true) { }
-
-ScopedFlock::~ScopedFlock() {
- if (file_.get() != nullptr) {
- int flock_result = TEMP_FAILURE_RETRY(flock(file_->Fd(), LOCK_UN));
+void LockedFile::ReleaseLock() {
+ if (this->Fd() != -1) {
+ int flock_result = TEMP_FAILURE_RETRY(flock(this->Fd(), LOCK_UN));
if (flock_result != 0) {
// Only printing a warning is okay since this is only used with either:
// 1) a non-blocking Init call, or
// 2) as a part of a seperate binary (eg dex2oat) which has it's own timeout logic to prevent
// deadlocks.
// This means we can be sure that the warning won't cause a deadlock.
- PLOG(WARNING) << "Unable to unlock file " << file_->GetPath();
- }
- int close_result = -1;
- if (file_->ReadOnlyMode() || !flush_on_close_) {
- close_result = file_->Close();
- } else {
- close_result = file_->FlushCloseOrErase();
- }
- if (close_result != 0) {
- PLOG(WARNING) << "Could not close scoped file lock file.";
+ PLOG(WARNING) << "Unable to unlock file " << this->GetPath();
}
}
}
diff --git a/runtime/base/scoped_flock.h b/runtime/base/scoped_flock.h
index a3a320f..1b933c0 100644
--- a/runtime/base/scoped_flock.h
+++ b/runtime/base/scoped_flock.h
@@ -20,63 +20,68 @@
#include <memory>
#include <string>
+#include "android-base/unique_fd.h"
+
+#include "base/logging.h"
#include "base/macros.h"
+#include "base/unix_file/fd_file.h"
#include "os.h"
namespace art {
-// A scoped file-lock implemented using flock. The file is locked by calling the Init function and
-// is released during destruction. Note that failing to unlock the file only causes a warning to be
-// printed. Users should take care that this does not cause potential deadlocks.
-//
-// Only printing a warning on unlock failure is okay since this is only used with either:
-// 1) a non-blocking Init call, or
-// 2) as a part of a seperate binary (eg dex2oat) which has it's own timeout logic to prevent
-// deadlocks.
-// This means we can be sure that the warning won't cause a deadlock.
-class ScopedFlock {
- public:
- ScopedFlock();
+class LockedFile;
+class LockedFileCloseNoFlush;
+// A scoped File object that calls Close without flushing.
+typedef std::unique_ptr<LockedFile, LockedFileCloseNoFlush> ScopedFlock;
+
+class LockedFile : public unix_file::FdFile {
+ public:
// Attempts to acquire an exclusive file lock (see flock(2)) on the file
// at filename, and blocks until it can do so.
//
- // Returns true if the lock could be acquired, or false if an error occurred.
// It is an error if its inode changed (usually due to a new file being
// created at the same path) between attempts to lock it. In blocking mode,
// locking will be retried if the file changed. In non-blocking mode, false
// is returned and no attempt is made to re-acquire the lock.
//
- // The argument `flush_on_close` controls whether or not the file
- // will be explicitly flushed before close.
- //
// The file is opened with the provided flags.
- bool Init(const char* filename,
- int flags,
- bool block,
- bool flush_on_close,
- std::string* error_msg);
- // Calls Init(filename, flags, block, true, error_msg);
- bool Init(const char* filename, int flags, bool block, std::string* error_msg);
- // Calls Init(filename, O_CREAT | O_RDWR, true, errror_msg)
- bool Init(const char* filename, std::string* error_msg);
+ static ScopedFlock Open(const char* filename, int flags, bool block,
+ std::string* error_msg);
+
+ // Calls Open(filename, O_CREAT | O_RDWR, true, errror_msg)
+ static ScopedFlock Open(const char* filename, std::string* error_msg);
+
// Attempt to acquire an exclusive file lock (see flock(2)) on 'file'.
// Returns true if the lock could be acquired or false if an error
// occured.
- bool Init(File* file, std::string* error_msg);
+ static ScopedFlock DupOf(const int fd, const std::string& path,
+ const bool read_only_mode, std::string* error_message);
- // Returns the (locked) file associated with this instance.
- File* GetFile() const;
-
- // Returns whether a file is held.
- bool HasFile();
-
- ~ScopedFlock();
+ // Release a lock held on this file, if any.
+ void ReleaseLock();
private:
- std::unique_ptr<File> file_;
- bool flush_on_close_;
- DISALLOW_COPY_AND_ASSIGN(ScopedFlock);
+ // Constructors should not be invoked directly, use one of the factory
+ // methods instead.
+ explicit LockedFile(FdFile&& other) : FdFile(std::move(other)) {
+ }
+
+ // Constructors should not be invoked directly, use one of the factory
+ // methods instead.
+ LockedFile(int fd, const std::string& path, bool check_usage, bool read_only_mode)
+ : FdFile(fd, path, check_usage, read_only_mode) {
+ }
+};
+
+class LockedFileCloseNoFlush {
+ public:
+ void operator()(LockedFile* ptr) {
+ ptr->ReleaseLock();
+ UNUSED(ptr->Close());
+
+ delete ptr;
+ }
};
} // namespace art
diff --git a/runtime/base/scoped_flock_test.cc b/runtime/base/scoped_flock_test.cc
index 1fa7a12..1b6caaf 100644
--- a/runtime/base/scoped_flock_test.cc
+++ b/runtime/base/scoped_flock_test.cc
@@ -30,11 +30,33 @@
// to each other, so attempting to query locks set by flock using
// using fcntl(,F_GETLK,) will not work. see kernel doc at
// Documentation/filesystems/locks.txt.
- ScopedFlock file_lock;
- ASSERT_TRUE(file_lock.Init(scratch_file.GetFilename().c_str(),
- &error_msg));
+ {
+ ScopedFlock file_lock = LockedFile::Open(scratch_file.GetFilename().c_str(),
+ &error_msg);
+ ASSERT_TRUE(file_lock.get() != nullptr);
- ASSERT_FALSE(file_lock.Init("/guaranteed/not/to/exist", &error_msg));
+ // Attempt to acquire a second lock on the same file. This must fail.
+ ScopedFlock second_lock = LockedFile::Open(scratch_file.GetFilename().c_str(),
+ O_RDONLY,
+ /* block */ false,
+ &error_msg);
+ ASSERT_TRUE(second_lock.get() == nullptr);
+ ASSERT_TRUE(!error_msg.empty());
+ }
+
+ {
+ // Attempt to reacquire the lock once the first lock has been released, this
+ // must succeed.
+ ScopedFlock file_lock = LockedFile::Open(scratch_file.GetFilename().c_str(),
+ &error_msg);
+ ASSERT_TRUE(file_lock.get() != nullptr);
+ }
+
+ {
+ ScopedFlock file_lock = LockedFile::Open("/will/not/exist",
+ &error_msg);
+ ASSERT_TRUE(file_lock.get() == nullptr);
+ }
}
} // namespace art
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 9da2876..1bf9285 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -482,21 +482,22 @@
bool validate_oat_file,
std::string* error_msg)
REQUIRES_SHARED(Locks::mutator_lock_) {
- // Note that we must not use the file descriptor associated with
- // ScopedFlock::GetFile to Init the image file. We want the file
- // descriptor (and the associated exclusive lock) to be released when
- // we leave Create.
- ScopedFlock image_lock;
// Should this be a RDWR lock? This is only a defensive measure, as at
// this point the image should exist.
// However, only the zygote can write into the global dalvik-cache, so
// restrict to zygote processes, or any process that isn't using
// /data/dalvik-cache (which we assume to be allowed to write there).
const bool rw_lock = is_zygote || !is_global_cache;
- image_lock.Init(image_filename.c_str(),
- rw_lock ? (O_CREAT | O_RDWR) : O_RDONLY /* flags */,
- true /* block */,
- error_msg);
+
+ // Note that we must not use the file descriptor associated with
+ // ScopedFlock::GetFile to Init the image file. We want the file
+ // descriptor (and the associated exclusive lock) to be released when
+ // we leave Create.
+ ScopedFlock image = LockedFile::Open(image_filename.c_str(),
+ rw_lock ? (O_CREAT | O_RDWR) : O_RDONLY /* flags */,
+ true /* block */,
+ error_msg);
+
VLOG(startup) << "Using image file " << image_filename.c_str() << " for image location "
<< image_location;
// If we are in /system we can assume the image is good. We can also
diff --git a/runtime/jit/profile_compilation_info.cc b/runtime/jit/profile_compilation_info.cc
index a67fb38..580be04 100644
--- a/runtime/jit/profile_compilation_info.cc
+++ b/runtime/jit/profile_compilation_info.cc
@@ -165,18 +165,20 @@
bool ProfileCompilationInfo::Load(const std::string& filename, bool clear_if_invalid) {
ScopedTrace trace(__PRETTY_FUNCTION__);
- ScopedFlock flock;
std::string error;
int flags = O_RDWR | O_NOFOLLOW | O_CLOEXEC;
// There's no need to fsync profile data right away. We get many chances
// to write it again in case something goes wrong. We can rely on a simple
// close(), no sync, and let to the kernel decide when to write to disk.
- if (!flock.Init(filename.c_str(), flags, /*block*/false, /*flush_on_close*/false, &error)) {
+ ScopedFlock profile_file = LockedFile::Open(filename.c_str(), flags,
+ /*block*/false, &error);
+
+ if (profile_file.get() == nullptr) {
LOG(WARNING) << "Couldn't lock the profile file " << filename << ": " << error;
return false;
}
- int fd = flock.GetFile()->Fd();
+ int fd = profile_file->Fd();
ProfileLoadSatus status = LoadInternal(fd, &error);
if (status == kProfileLoadSuccess) {
@@ -187,7 +189,7 @@
((status == kProfileLoadVersionMismatch) || (status == kProfileLoadBadData))) {
LOG(WARNING) << "Clearing bad or obsolete profile data from file "
<< filename << ": " << error;
- if (flock.GetFile()->ClearContent()) {
+ if (profile_file->ClearContent()) {
return true;
} else {
PLOG(WARNING) << "Could not clear profile file: " << filename;
@@ -201,21 +203,22 @@
bool ProfileCompilationInfo::Save(const std::string& filename, uint64_t* bytes_written) {
ScopedTrace trace(__PRETTY_FUNCTION__);
- ScopedFlock flock;
std::string error;
int flags = O_WRONLY | O_NOFOLLOW | O_CLOEXEC;
// There's no need to fsync profile data right away. We get many chances
// to write it again in case something goes wrong. We can rely on a simple
// close(), no sync, and let to the kernel decide when to write to disk.
- if (!flock.Init(filename.c_str(), flags, /*block*/false, /*flush_on_close*/false, &error)) {
+ ScopedFlock profile_file = LockedFile::Open(filename.c_str(), flags,
+ /*block*/false, &error);
+ if (profile_file.get() == nullptr) {
LOG(WARNING) << "Couldn't lock the profile file " << filename << ": " << error;
return false;
}
- int fd = flock.GetFile()->Fd();
+ int fd = profile_file->Fd();
// We need to clear the data because we don't support appending to the profiles yet.
- if (!flock.GetFile()->ClearContent()) {
+ if (!profile_file->ClearContent()) {
PLOG(WARNING) << "Could not clear profile file: " << filename;
return false;
}
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
index 2e2e8c3..4820feb 100644
--- a/runtime/oat_file_assistant.cc
+++ b/runtime/oat_file_assistant.cc
@@ -141,8 +141,8 @@
OatFileAssistant::~OatFileAssistant() {
// Clean up the lock file.
- if (flock_.HasFile()) {
- unlink(flock_.GetFile()->GetPath().c_str());
+ if (flock_.get() != nullptr) {
+ unlink(flock_->GetPath().c_str());
}
}
@@ -165,7 +165,7 @@
bool OatFileAssistant::Lock(std::string* error_msg) {
CHECK(error_msg != nullptr);
- CHECK(!flock_.HasFile()) << "OatFileAssistant::Lock already acquired";
+ CHECK(flock_.get() == nullptr) << "OatFileAssistant::Lock already acquired";
// Note the lock will only succeed for secondary dex files and in test
// environment.
@@ -179,7 +179,8 @@
// to generate oat files anyway.
std::string lock_file_name = dex_location_ + "." + GetInstructionSetString(isa_) + ".flock";
- if (!flock_.Init(lock_file_name.c_str(), error_msg)) {
+ flock_ = LockedFile::Open(lock_file_name.c_str(), error_msg);
+ if (flock_.get() == nullptr) {
unlink(lock_file_name.c_str());
return false;
}