195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor//===--- LockFileManager.cpp - File-level Locking Utility------------------===// 295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor// 395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor// The LLVM Compiler Infrastructure 495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor// 595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor// This file is distributed under the University of Illinois Open Source 695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor// License. See LICENSE.TXT for details. 795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor// 895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor//===----------------------------------------------------------------------===// 995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#include "llvm/Support/LockFileManager.h" 1095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#include "llvm/Support/FileSystem.h" 1195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#include "llvm/Support/raw_ostream.h" 1295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#include <fstream> 1395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#include <sys/types.h> 1495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#include <sys/stat.h> 1595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#if LLVM_ON_WIN32 1695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#include <windows.h> 1795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#endif 1895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#if LLVM_ON_UNIX 1995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#include <unistd.h> 2095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#endif 2195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregorusing namespace llvm; 2295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 2395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor/// \brief Attempt to read the lock file with the given name, if it exists. 2495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor/// 2595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor/// \param LockFileName The name of the lock file to read. 2695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor/// 2795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor/// \returns The process ID of the process that owns this lock file 2895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas GregorOptional<std::pair<std::string, int> > 2995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas GregorLockFileManager::readLockFile(StringRef LockFileName) { 3095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // Check whether the lock file exists. If not, clearly there's nothing 3195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // to read, so we just return. 3295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor bool Exists = false; 3395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if (sys::fs::exists(LockFileName, Exists) || !Exists) 3495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return Optional<std::pair<std::string, int> >(); 3595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 3695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // Read the owning host and PID out of the lock file. If it appears that the 3795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // owning process is dead, the lock file is invalid. 3895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor int PID = 0; 3995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor std::string Hostname; 4095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor std::ifstream Input(LockFileName.str().c_str()); 4195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if (Input >> Hostname >> PID && PID > 0 && 4295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor processStillExecuting(Hostname, PID)) 4395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return std::make_pair(Hostname, PID); 4495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 4595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // Delete the lock file. It's invalid anyway. 4695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor bool Existed; 4795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor sys::fs::remove(LockFileName, Existed); 4895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return Optional<std::pair<std::string, int> >(); 4995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor} 5095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 5195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregorbool LockFileManager::processStillExecuting(StringRef Hostname, int PID) { 5268d92bdcc99e647546f40cfce5cfbeb904be2985Evgeniy Stepanov#if LLVM_ON_UNIX && !defined(__ANDROID__) 5395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor char MyHostname[256]; 5495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor MyHostname[255] = 0; 5595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor MyHostname[0] = 0; 5695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor gethostname(MyHostname, 255); 5795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // Check whether the process is dead. If so, we're done. 5895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if (MyHostname == Hostname && getsid(PID) == -1 && errno == ESRCH) 5995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return false; 6095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#endif 6195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 6295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return true; 6395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor} 6495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 6595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas GregorLockFileManager::LockFileManager(StringRef FileName) 6695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor{ 6795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor LockFileName = FileName; 6895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor LockFileName += ".lock"; 6995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 7095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // If the lock file already exists, don't bother to try to create our own 7195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // lock file; it won't work anyway. Just figure out who owns this lock file. 7295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if ((Owner = readLockFile(LockFileName))) 7395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return; 7495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 7595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // Create a lock file that is unique to this instance. 7695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor UniqueLockFileName = LockFileName; 7795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor UniqueLockFileName += "-%%%%%%%%"; 7895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor int UniqueLockFileID; 7995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if (error_code EC 8095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor = sys::fs::unique_file(UniqueLockFileName.str(), 8195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor UniqueLockFileID, 8295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor UniqueLockFileName, 8395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor /*makeAbsolute=*/false)) { 8495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Error = EC; 8595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return; 8695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor } 8795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 8895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // Write our process ID to our unique lock file. 8995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor { 9095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor raw_fd_ostream Out(UniqueLockFileID, /*shouldClose=*/true); 9195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 9295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#if LLVM_ON_UNIX 9395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // FIXME: move getpid() call into LLVM 9495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor char hostname[256]; 9595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor hostname[255] = 0; 9695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor hostname[0] = 0; 9795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor gethostname(hostname, 255); 9895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Out << hostname << ' ' << getpid(); 9995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#else 10095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Out << "localhost 1"; 10195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#endif 10295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Out.close(); 10395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 10495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if (Out.has_error()) { 10595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // We failed to write out PID, so make up an excuse, remove the 10695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // unique lock file, and fail. 10795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Error = make_error_code(errc::no_space_on_device); 10895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor bool Existed; 10995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor sys::fs::remove(UniqueLockFileName.c_str(), Existed); 11095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return; 11195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor } 11295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor } 11395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 11495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // Create a hard link from the lock file name. If this succeeds, we're done. 11595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor error_code EC 11695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor = sys::fs::create_hard_link(UniqueLockFileName.str(), 11795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor LockFileName.str()); 11895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if (EC == errc::success) 11995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return; 12095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 12195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // Creating the hard link failed. 12295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 12395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#ifdef LLVM_ON_UNIX 12495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // The creation of the hard link may appear to fail, but if stat'ing the 12595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // unique file returns a link count of 2, then we can still declare success. 12695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor struct stat StatBuf; 12795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if (stat(UniqueLockFileName.c_str(), &StatBuf) == 0 && 12895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor StatBuf.st_nlink == 2) 12995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return; 13095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#endif 13195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 13295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // Someone else managed to create the lock file first. Wipe out our unique 13395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // lock file (it's useless now) and read the process ID from the lock file. 13495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor bool Existed; 13595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor sys::fs::remove(UniqueLockFileName.str(), Existed); 13695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if ((Owner = readLockFile(LockFileName))) 13795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return; 13895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 13995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // There is a lock file that nobody owns; try to clean it up and report 14095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // an error. 14195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor sys::fs::remove(LockFileName.str(), Existed); 14295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Error = EC; 14395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor} 14495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 14595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas GregorLockFileManager::LockFileState LockFileManager::getState() const { 14695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if (Owner) 14795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return LFS_Shared; 14895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 14995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if (Error) 15095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return LFS_Error; 15195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 15295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return LFS_Owned; 15395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor} 15495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 15595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas GregorLockFileManager::~LockFileManager() { 15695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if (getState() != LFS_Owned) 15795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return; 15895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 15995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // Since we own the lock, remove the lock file and our own unique lock file. 16095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor bool Existed; 16195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor sys::fs::remove(LockFileName.str(), Existed); 16295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor sys::fs::remove(UniqueLockFileName.str(), Existed); 16395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor} 16495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 16595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregorvoid LockFileManager::waitForUnlock() { 16695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if (getState() != LFS_Shared) 16795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return; 16895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 16995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#if LLVM_ON_WIN32 17095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor unsigned long Interval = 1; 17195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#else 17295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor struct timespec Interval; 17395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Interval.tv_sec = 0; 17495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Interval.tv_nsec = 1000000; 17595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#endif 17695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // Don't wait more than an hour for the file to appear. 17795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor const unsigned MaxSeconds = 3600; 17895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor do { 17995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // Sleep for the designated interval, to allow the owning process time to 18095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // finish up and remove the lock file. 18195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // FIXME: Should we hook in to system APIs to get a notification when the 18295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // lock file is deleted? 18395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#if LLVM_ON_WIN32 18495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Sleep(Interval); 18595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#else 18695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor nanosleep(&Interval, NULL); 18795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#endif 18895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // If the file no longer exists, we're done. 18995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor bool Exists = false; 19095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if (!sys::fs::exists(LockFileName.str(), Exists) && !Exists) 19195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return; 19295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 19395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if (!processStillExecuting((*Owner).first, (*Owner).second)) 19495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor return; 19595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 19695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // Exponentially increase the time we wait for the lock to be removed. 19795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#if LLVM_ON_WIN32 19895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Interval *= 2; 19995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#else 20095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Interval.tv_sec *= 2; 20195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Interval.tv_nsec *= 2; 20295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor if (Interval.tv_nsec >= 1000000000) { 20395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor ++Interval.tv_sec; 20495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Interval.tv_nsec -= 1000000000; 20595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor } 20695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#endif 20795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor } while ( 20895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#if LLVM_ON_WIN32 20995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Interval < MaxSeconds * 1000 21095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#else 21195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Interval.tv_sec < (time_t)MaxSeconds 21295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#endif 21395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor ); 21495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 21595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor // Give up. 21695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor} 217