private void HandleLockRequest(NamedPipeServer.Connection connection, NamedPipeMessages.Message message) { NamedPipeMessages.AcquireLock.Response response; NamedPipeMessages.AcquireLock.Data externalHolder; NamedPipeMessages.AcquireLock.Request request = new NamedPipeMessages.AcquireLock.Request(message); NamedPipeMessages.AcquireLock.Data requester = request.RequestData; if (request == null) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.UnknownRequest, requester); } else if (this.currentState != MountState.Ready) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.MountNotReadyResult); } else { bool lockAcquired = this.gvfsLock.TryAcquireLock(requester, out externalHolder); if (lockAcquired) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.AcceptResult); } else if (externalHolder == null) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGVFSResult); } else { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGitResult, externalHolder); } } connection.TrySendResponse(response.CreateMessage()); }
private static void AcquireGlobalLock(string[] args) { try { if (ShouldLock(args)) { GVFSEnlistment enlistment = GVFSEnlistment.CreateFromCurrentDirectory(null, GitProcess.GetInstalledGitBinPath()); if (enlistment == null) { ExitWithError("This hook must be run from a GVFS repo"); } if (EnlistmentIsReady(enlistment)) { string fullCommand = "git " + string.Join(" ", args.Skip(1)); int pid = ProcessHelper.GetParentProcessId("git.exe"); Process parentProcess = null; if (pid == GVFSConstants.InvalidProcessId || !ProcessHelper.TryGetProcess(pid, out parentProcess)) { ExitWithError("GVFS.Hooks: Unable to find parent git.exe process " + "(PID: " + pid + ")."); } using (NamedPipeClient pipeClient = new NamedPipeClient(enlistment.NamedPipeName)) { if (!pipeClient.Connect()) { ExitWithError("The enlistment does not appear to be mounted. Use 'gvfs status' to check."); } NamedPipeMessages.AcquireLock.Request request = new NamedPipeMessages.AcquireLock.Request(pid, fullCommand, ProcessHelper.GetCommandLine(parentProcess)); NamedPipeMessages.Message requestMessage = request.CreateMessage(); pipeClient.SendRequest(requestMessage); NamedPipeMessages.AcquireLock.Response response = new NamedPipeMessages.AcquireLock.Response(pipeClient.ReadResponse()); if (response.Result == NamedPipeMessages.AcquireLock.AcceptResult) { return; } else if (response.Result == NamedPipeMessages.AcquireLock.MountNotReadyResult) { ExitWithError("GVFS has not finished initializing, please wait a few seconds and try again."); } else { int retries = 0; char[] waiting = { '\u2014', '\\', '|', '/' }; string message = string.Empty; while (true) { if (response.Result == NamedPipeMessages.AcquireLock.AcceptResult) { if (!Console.IsOutputRedirected) { Console.WriteLine("\r{0}...", message); } return; } else if (response.Result == NamedPipeMessages.AcquireLock.DenyGVFSResult) { message = "Waiting for GVFS to release the lock"; } else if (response.Result == NamedPipeMessages.AcquireLock.DenyGitResult) { message = string.Format("Waiting for '{0}' to release the lock", response.ResponseData.ParsedCommand); } else { ExitWithError("Error when acquiring the lock. Unrecognized response: " + response.CreateMessage()); tracer.RelatedError("Unknown LockRequestResponse: " + response); } if (Console.IsOutputRedirected && retries == 0) { Console.WriteLine("{0}...", message); } else if (!Console.IsOutputRedirected) { Console.Write("\r{0}..{1}", message, waiting[retries % waiting.Length]); } Thread.Sleep(500); pipeClient.SendRequest(requestMessage); response = new NamedPipeMessages.AcquireLock.Response(pipeClient.ReadResponse()); retries++; } } } } } } catch (Exception e) { EventMetadata metadata = new EventMetadata(); metadata.Add("Error", e.ToString()); tracer.RelatedError(metadata); ExitWithError( "Unable to initialize Git command.", "Ensure that GVFS is running."); } }