@@ -51,7 +51,7 @@ using namespace llvm;
5151// / \param LockFileName The name of the lock file to read.
5252// /
5353// / \returns The process ID of the process that owns this lock file
54- std::optional<std::pair<std::string, int > >
54+ std::optional<LockFileManager::OwnedByAnother >
5555LockFileManager::readLockFile (StringRef LockFileName) {
5656 // Read the owning host and PID out of the lock file. If it appears that the
5757 // owning process is dead, the lock file is invalid.
@@ -69,8 +69,10 @@ LockFileManager::readLockFile(StringRef LockFileName) {
6969 PIDStr = PIDStr.substr (PIDStr.find_first_not_of (' ' ));
7070 int PID;
7171 if (!PIDStr.getAsInteger (10 , PID)) {
72- auto Owner = std::make_pair (std::string (Hostname), PID);
73- if (processStillExecuting (Owner.first , Owner.second ))
72+ OwnedByAnother Owner;
73+ Owner.OwnerHostName = Hostname;
74+ Owner.OwnerPID = PID;
75+ if (processStillExecuting (Owner.OwnerHostName , Owner.OwnerPID ))
7476 return Owner;
7577 }
7678
@@ -158,41 +160,40 @@ class RemoveUniqueLockFileOnSignal {
158160} // end anonymous namespace
159161
160162LockFileManager::LockFileManager (StringRef FileName)
161- {
162- this ->FileName = FileName;
163- if (std::error_code EC = sys::fs::make_absolute (this ->FileName )) {
164- std::string S (" failed to obtain absolute path for " );
165- S.append (std::string (this ->FileName ));
166- setError (EC, S);
167- return ;
168- }
169- LockFileName = this ->FileName ;
163+ : FileName(FileName), Owner(OwnerUnknown{}) {}
164+
165+ Expected<bool > LockFileManager::tryLock () {
166+ assert (std::holds_alternative<OwnerUnknown>(Owner) &&
167+ " lock has already been attempted" );
168+
169+ SmallString<128 > AbsoluteFileName (FileName);
170+ if (std::error_code EC = sys::fs::make_absolute (AbsoluteFileName))
171+ return createStringError (EC, " failed to obtain absolute path for " +
172+ AbsoluteFileName);
173+ LockFileName = AbsoluteFileName;
170174 LockFileName += " .lock" ;
171175
172176 // If the lock file already exists, don't bother to try to create our own
173177 // lock file; it won't work anyway. Just figure out who owns this lock file.
174- if ((Owner = readLockFile (LockFileName)))
175- return ;
178+ if (auto LockFileOwner = readLockFile (LockFileName)) {
179+ Owner = std::move (*LockFileOwner);
180+ return false ;
181+ }
176182
177183 // Create a lock file that is unique to this instance.
178184 UniqueLockFileName = LockFileName;
179185 UniqueLockFileName += " -%%%%%%%%" ;
180186 int UniqueLockFileID;
181187 if (std::error_code EC = sys::fs::createUniqueFile (
182- UniqueLockFileName, UniqueLockFileID, UniqueLockFileName)) {
183- std::string S (" failed to create unique file " );
184- S.append (std::string (UniqueLockFileName));
185- setError (EC, S);
186- return ;
187- }
188+ UniqueLockFileName, UniqueLockFileID, UniqueLockFileName))
189+ return createStringError (EC, " failed to create unique file " +
190+ UniqueLockFileName);
188191
189192 // Write our process ID to our unique lock file.
190193 {
191194 SmallString<256 > HostID;
192- if (auto EC = getHostID (HostID)) {
193- setError (EC, " failed to get host id" );
194- return ;
195- }
195+ if (auto EC = getHostID (HostID))
196+ return createStringError (EC, " failed to get host id" );
196197
197198 raw_fd_ostream Out (UniqueLockFileID, /* shouldClose=*/ true );
198199 Out << HostID << ' ' << sys::Process::getProcessId ();
@@ -201,13 +202,12 @@ LockFileManager::LockFileManager(StringRef FileName)
201202 if (Out.has_error ()) {
202203 // We failed to write out PID, so report the error, remove the
203204 // unique lock file, and fail.
204- std::string S (" failed to write to " );
205- S.append (std::string (UniqueLockFileName));
206- setError (Out.error (), S);
205+ Error Err = createStringError (Out.error (),
206+ " failed to write to " + UniqueLockFileName);
207207 sys::fs::remove (UniqueLockFileName);
208208 // Don't call report_fatal_error.
209209 Out.clear_error ();
210- return ;
210+ return std::move (Err) ;
211211 }
212212 }
213213
@@ -221,23 +221,21 @@ LockFileManager::LockFileManager(StringRef FileName)
221221 sys::fs::create_link (UniqueLockFileName, LockFileName);
222222 if (!EC) {
223223 RemoveUniqueFile.lockAcquired ();
224- return ;
224+ Owner = OwnedByUs{};
225+ return true ;
225226 }
226227
227- if (EC != errc::file_exists) {
228- std::string S (" failed to create link " );
229- raw_string_ostream OSS (S);
230- OSS << LockFileName.str () << " to " << UniqueLockFileName.str ();
231- setError (EC, S);
232- return ;
233- }
228+ if (EC != errc::file_exists)
229+ return createStringError (EC, " failed to create link " + LockFileName +
230+ " to " + UniqueLockFileName);
234231
235232 // Someone else managed to create the lock file first. Read the process ID
236233 // from the lock file.
237- if ((Owner = readLockFile (LockFileName) )) {
234+ if (auto LockFileOwner = readLockFile (LockFileName)) {
238235 // Wipe out our unique lock file (it's useless now)
239236 sys::fs::remove (UniqueLockFileName);
240- return ;
237+ Owner = std::move (*LockFileOwner);
238+ return false ;
241239 }
242240
243241 if (!sys::fs::exists (LockFileName)) {
@@ -248,39 +246,14 @@ LockFileManager::LockFileManager(StringRef FileName)
248246
249247 // There is a lock file that nobody owns; try to clean it up and get
250248 // ownership.
251- if ((EC = sys::fs::remove (LockFileName))) {
252- std::string S (" failed to remove lockfile " );
253- S.append (std::string (UniqueLockFileName));
254- setError (EC, S);
255- return ;
256- }
257- }
258- }
259-
260- LockFileManager::LockFileState LockFileManager::getState () const {
261- if (Owner)
262- return LFS_Shared;
263-
264- if (ErrorCode)
265- return LFS_Error;
266-
267- return LFS_Owned;
268- }
269-
270- std::string LockFileManager::getErrorMessage () const {
271- if (ErrorCode) {
272- std::string Str (ErrorDiagMsg);
273- std::string ErrCodeMsg = ErrorCode.message ();
274- raw_string_ostream OSS (Str);
275- if (!ErrCodeMsg.empty ())
276- OSS << " : " << ErrCodeMsg;
277- return Str;
249+ if ((EC = sys::fs::remove (LockFileName)))
250+ return createStringError (EC, " failed to remove lockfile " +
251+ UniqueLockFileName);
278252 }
279- return " " ;
280253}
281254
282255LockFileManager::~LockFileManager () {
283- if (getState () != LFS_Owned )
256+ if (!std::holds_alternative<OwnedByUs>(Owner) )
284257 return ;
285258
286259 // Since we own the lock, remove the lock file and our own unique lock file.
@@ -293,8 +266,9 @@ LockFileManager::~LockFileManager() {
293266
294267LockFileManager::WaitForUnlockResult
295268LockFileManager::waitForUnlock (const unsigned MaxSeconds) {
296- if (getState () != LFS_Shared)
297- return Res_Success;
269+ auto *LockFileOwner = std::get_if<OwnedByAnother>(&Owner);
270+ assert (LockFileOwner &&
271+ " waiting for lock to be unlocked without knowing the owner" );
298272
299273 // Since we don't yet have an event-based method to wait for the lock file,
300274 // use randomized exponential backoff, similar to Ethernet collision
@@ -311,7 +285,8 @@ LockFileManager::waitForUnlock(const unsigned MaxSeconds) {
311285 return Res_Success;
312286
313287 // If the process owning the lock died without cleaning up, just bail out.
314- if (!processStillExecuting ((*Owner).first , (*Owner).second ))
288+ if (!processStillExecuting (LockFileOwner->OwnerHostName ,
289+ LockFileOwner->OwnerPID ))
315290 return Res_OwnerDied;
316291 }
317292
0 commit comments