From 69a2d6f55afb2bc42bc19e754bcebee39ecdb8bc Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 10 Jan 2013 02:01:35 +0000 Subject: Fix a race condition in the lock-file manager: once the lock file is gone, check for the actual file we care about. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172033 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/LockFileManager.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'lib/Support/LockFileManager.cpp') diff --git a/lib/Support/LockFileManager.cpp b/lib/Support/LockFileManager.cpp index 075d8a5a66..31eec751b7 100644 --- a/lib/Support/LockFileManager.cpp +++ b/lib/Support/LockFileManager.cpp @@ -64,6 +64,7 @@ bool LockFileManager::processStillExecuting(StringRef Hostname, int PID) { LockFileManager::LockFileManager(StringRef FileName) { + this->FileName = FileName; LockFileName = FileName; LockFileName += ".lock"; @@ -175,6 +176,7 @@ void LockFileManager::waitForUnlock() { #endif // Don't wait more than an hour for the file to appear. const unsigned MaxSeconds = 3600; + bool LockFileGone = false; do { // Sleep for the designated interval, to allow the owning process time to // finish up and remove the lock file. @@ -185,10 +187,18 @@ void LockFileManager::waitForUnlock() { #else nanosleep(&Interval, NULL); #endif - // If the file no longer exists, we're done. + // If the lock file no longer exists, wait for the actual file. bool Exists = false; - if (!sys::fs::exists(LockFileName.str(), Exists) && !Exists) - return; + if (!LockFileGone) { + if (!sys::fs::exists(LockFileName.str(), Exists) && !Exists) { + LockFileGone = true; + Exists = false; + } + } + if (LockFileGone) { + if (!sys::fs::exists(FileName.str(), Exists) && Exists) + return; + } if (!processStillExecuting((*Owner).first, (*Owner).second)) return; -- cgit v1.2.3-70-g09d2 From 5c43245bf459c77077b607e1b55e6928cfbe464e Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Thu, 21 Feb 2013 00:27:28 +0000 Subject: Provide a "None" value for convenience when using Optional() This implementation of NoneType/None does have some holes but I haven't found one that doesn't - open to improvement. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175696 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/None.h | 27 +++++++++++++++++++++++++++ include/llvm/ADT/Optional.h | 2 ++ lib/Support/LockFileManager.cpp | 4 ++-- 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 include/llvm/ADT/None.h (limited to 'lib/Support/LockFileManager.cpp') diff --git a/include/llvm/ADT/None.h b/include/llvm/ADT/None.h new file mode 100644 index 0000000000..83c952178a --- /dev/null +++ b/include/llvm/ADT/None.h @@ -0,0 +1,27 @@ +//===-- None.h - Simple null value for implicit construction ------*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides None, an enumerant for use in implicit constructors +// of various (usually templated) types to make such construction more +// terse. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_NONE_H +#define LLVM_ADT_NONE_H + +namespace llvm { +/// \brief A simple null object to allow implicit construction of Optional +/// and similar types without having to spell out the specialization's name. +enum NoneType { + None +}; +} + +#endif diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h index 6c91a13a5b..b0d09f6960 100644 --- a/include/llvm/ADT/Optional.h +++ b/include/llvm/ADT/Optional.h @@ -16,6 +16,7 @@ #ifndef LLVM_ADT_OPTIONAL_H #define LLVM_ADT_OPTIONAL_H +#include "llvm/ADT/None.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/AlignOf.h" #include @@ -31,6 +32,7 @@ class Optional { AlignedCharArrayUnion storage; bool hasVal; public: + Optional(NoneType) : hasVal(false) {} explicit Optional() : hasVal(false) {} Optional(const T &y) : hasVal(true) { new (storage.buffer) T(y); diff --git a/lib/Support/LockFileManager.cpp b/lib/Support/LockFileManager.cpp index 31eec751b7..92d8b83cf9 100644 --- a/lib/Support/LockFileManager.cpp +++ b/lib/Support/LockFileManager.cpp @@ -31,7 +31,7 @@ LockFileManager::readLockFile(StringRef LockFileName) { // to read, so we just return. bool Exists = false; if (sys::fs::exists(LockFileName, Exists) || !Exists) - return Optional >(); + return None; // Read the owning host and PID out of the lock file. If it appears that the // owning process is dead, the lock file is invalid. @@ -45,7 +45,7 @@ LockFileManager::readLockFile(StringRef LockFileName) { // Delete the lock file. It's invalid anyway. bool Existed; sys::fs::remove(LockFileName, Existed); - return Optional >(); + return None; } bool LockFileManager::processStillExecuting(StringRef Hostname, int PID) { -- cgit v1.2.3-70-g09d2