private async Task WaitUntilReportEof(bool cancel) { using (await m_reportReaderSemaphore.AcquireAsync()) { if (m_reportReader != null) { await m_reportReader.CompletionAsync(!cancel); m_reportReader.Dispose(); m_reportReader = null; } } }
public ProcessTreeContext( Guid payloadGuid, SafeHandle reportPipe, ArraySegment <byte> payload, string dllNameX64, string dllNameX86, int numRetriesPipeReadOnCancel, Action <string> debugPipeReporter, LoggingContext loggingContext) { // We cannot create this object in a wow64 process Contract.Assume( !ProcessUtilities.IsWow64Process(), "ProcessTreeContext:ctor - Cannot run injection server in a wow64 32 bit process"); SafeFileHandle childHandle = null; m_loggingContext = loggingContext; NamedPipeServerStream serverStream = null; bool useNonDefaultPipeReader = PipeReaderFactory.GetKind() != PipeReaderFactory.Kind.Default; // This object will be the server for the tree. CreateSourceFile the pipe server. try { SafeFileHandle injectorHandle = null; if (useNonDefaultPipeReader) { serverStream = Pipes.CreateNamedPipeServerStream( PipeDirection.In, PipeOptions.Asynchronous, PipeOptions.None, out childHandle); } else { // Create a pipe for the requests Pipes.CreateInheritablePipe(Pipes.PipeInheritance.InheritWrite, Pipes.PipeFlags.ReadSideAsync, out injectorHandle, out childHandle); } // Create the injector. This will duplicate the handles. Injector = ProcessUtilities.CreateProcessInjector(payloadGuid, childHandle, reportPipe, dllNameX86, dllNameX64, payload); if (useNonDefaultPipeReader) { m_injectionRequestReader = PipeReaderFactory.CreateNonDefaultPipeReader( serverStream, InjectCallback, Encoding.Unicode, BufferSize); } else { // Create the request reader. We don't start listening until requested var injectionRequestFile = AsyncFileFactory.CreateAsyncFile( injectorHandle, FileDesiredAccess.GenericRead, ownsHandle: true, kind: FileKind.Pipe); m_injectionRequestReader = new AsyncPipeReader( injectionRequestFile, InjectCallback, Encoding.Unicode, BufferSize, numOfRetriesOnCancel: numRetriesPipeReadOnCancel, debugPipeReporter: new AsyncPipeReader.DebugReporter(debugMsg => debugPipeReporter?.Invoke($"InjectionRequestReader: {debugMsg}"))); } } catch (Exception exception) { if (Injector != null) { Injector.Dispose(); Injector = null; } if (m_injectionRequestReader != null) { m_injectionRequestReader.Dispose(); m_injectionRequestReader = null; } throw new BuildXLException("Process Tree Context injector could not be created", exception); } finally { // Release memory. Since the child handle is duplicated, it can be released if (childHandle != null && !childHandle.IsInvalid) { childHandle.Dispose(); } } }