private bool IsExternalProcessAlive() { lock (this.acquisitionLock) { if (this.isHeldInternally) { if (this.lockHolder != null) { throw new InvalidOperationException("Inconsistent GVFSLock state with external holder " + this.lockHolder.ToString()); } return(false); } if (this.lockHolder == null) { return(false); } Process process; if (ProcessHelper.TryGetProcess(this.lockHolder.PID, out process) && string.Equals(this.lockHolder.OriginalCommand, ProcessHelper.GetCommandLine(process))) { return(true); } this.ClearHolder(); return(false); } }
/// <summary> /// Allows external callers (non-GVFS) to acquire the lock. /// </summary> /// <param name="requester">The data for the external acquisition request.</param> /// <param name="holder"> /// The current holder of the lock if the acquisition fails, or /// the input request if it succeeds. /// </param> /// <returns>True if the lock was acquired, false otherwise.</returns> public bool TryAcquireLock( NamedPipeMessages.AcquireLock.Data requester, out NamedPipeMessages.AcquireLock.Data holder) { EventMetadata metadata = new EventMetadata(); EventLevel eventLevel = EventLevel.Verbose; metadata.Add("LockRequest", requester.ToString()); try { lock (this.acquisitionLock) { if (this.isHeldInternally) { holder = null; metadata.Add("CurrentLockHolder", "GVFS"); metadata.Add("Result", "Denied"); return(false); } if (this.IsExternalProcessAlive() && this.lockHolder.PID != requester.PID) { holder = this.lockHolder; metadata.Add("CurrentLockHolder", this.lockHolder.ToString()); metadata.Add("Result", "Denied"); return(false); } metadata.Add("Result", "Accepted"); eventLevel = EventLevel.Informational; Process process; if (ProcessHelper.TryGetProcess(requester.PID, out process) && string.Equals(requester.OriginalCommand, ProcessHelper.GetCommandLine(process))) { this.lockHolder = requester; holder = requester; return(true); } else { // Process is no longer running so let it // succeed since the process non-existence // signals the lock release. holder = null; return(true); } } } finally { this.tracer.RelatedEvent(eventLevel, "TryAcquireLockExternal", metadata); } }