public bool Lock(string operationName) { Stream lockStream = null; var ignoreCloseStreamException = false; try { FileSystemHelpers.EnsureDirectory(Path.GetDirectoryName(_path)); lockStream = FileSystemHelpers.OpenFile(_path, FileMode.Create, FileAccess.Write, FileShare.Read); WriteLockInfo(operationName, lockStream); OnLockAcquired(); _lockStream = lockStream; lockStream = null; _traceFactory.GetTracer().Trace($"LockFile '{_path}' acquired"); return(true); } catch (UnauthorizedAccessException) { if (!_ensureLock) { // if it is ReadOnly file system, we will skip the lock // which will enable all read action // for write action, it will fail with UnauthorizedAccessException when perform actual write operation // There is one drawback, previously for write action, even acquire lock will fail with UnauthorizedAccessException, // there will be retry within given timeout. so if exception is temporary, previous`s implementation will still go thru. // While right now will end up failure. But it is a extreme edge case, should be ok to ignore. ignoreCloseStreamException = FileSystemHelpers.IsFileSystemReadOnly(); return(ignoreCloseStreamException); } } catch (IOException ex) { if (!_ensureLock) { // if not enough disk space, no one has the lock. // let the operation thru and fail where it would try to get the file ignoreCloseStreamException = ex.Message.Contains(NotEnoughSpaceText); return(ignoreCloseStreamException); } } catch (Exception ex) { TraceIfUnknown(ex); } finally { if (lockStream != null) { OperationManager.CriticalExecute("LockFile.Lock.Finally", () => lockStream.Close(), _ => !ignoreCloseStreamException); } } return(false); }
public void Release() { // Normally, this should never be null here, but currently some LiveScmEditorController code calls Release() incorrectly if (_lockStream == null) { OnLockRelease(); return; } OperationManager.CriticalExecute("LockFile.Release", () => { var temp = _lockStream; _lockStream = null; temp.Close(); if (_traceLock) { _traceFactory.GetTracer().Trace($"LockFile '{_path}' released"); } }); // cleanup inactive lock file. technically, it is not needed // we just want to see the lock folder is clean, if no active lock. DeleteFileSafe(); OnLockRelease(); }