/// <summary> /// Creates a new AsyncStreamReader for the given stream. The /// character encoding is set by encoding and the buffer size, /// in number of 16-bit characters, is set by bufferSize. /// </summary> public AsyncPipeReader( IAsyncFile file, StreamDataReceived callback, Encoding encoding, int bufferSize) { Contract.Requires(file != null); Contract.Requires(file.CanRead); Contract.Requires(file.Kind == FileKind.Pipe); Contract.Requires(encoding != null); Contract.Requires(bufferSize > 128); m_file = file; m_userCallBack = callback; m_decoder = encoding.GetDecoder(); m_pooledByteBufferWrapper = Pools.GetByteArray(bufferSize); m_byteBufferSize = bufferSize; m_byteBufferPin = GCHandle.Alloc(ByteBuffer, GCHandleType.Pinned); m_byteBufferPtr = (byte *)m_byteBufferPin.AddrOfPinnedObject(); var maxCharsPerBuffer = encoding.GetMaxCharCount(bufferSize); m_pooledCharBufferWrapper = Pools.GetCharArray(maxCharsPerBuffer); m_pooledStringBuilderWrapper = Pools.GetStringBuilder(); StringBuilderInstace.Clear(); StringBuilderInstace.EnsureCapacity(maxCharsPerBuffer * 2); }
/// <summary> /// Constructor. /// </summary> public StreamAsyncPipeReader( NamedPipeServerStream pipeStream, StreamDataReceived callback, Encoding encoding, int bufferSize) { m_pipeStream = pipeStream; m_userCallBack = callback; m_reader = new StreamReader(pipeStream, encoding, false, bufferSize); }
public DetouredProcess( int bufferSize, string commandLine, string workingDirectory, byte[] unicodeEnvironmentBlock, Encoding standardInputEncoding, Encoding standardErrorEncoding, StreamDataReceived errorDataReceived, Encoding standardOutputEncoding, StreamDataReceived outputDataReceived, Func <Task> processExitingAsync, Func <Task> processExited, TimeSpan?timeout, bool disableConHostSharing, LoggingContext loggingContext, string timeoutDumpDirectory, ContainerConfiguration containerConfiguration, bool setJobBreakawayOk, bool createJobObjectForCurrentProcess) { Contract.Requires(bufferSize >= 128); Contract.Requires(!string.IsNullOrEmpty(commandLine)); Contract.Requires(standardInputEncoding != null); Contract.Requires(standardErrorEncoding != null); Contract.Requires(standardOutputEncoding != null); Contract.Requires(!timeout.HasValue || timeout.Value <= Process.MaxTimeout); m_bufferSize = bufferSize; m_commandLine = commandLine; m_workingDirectory = workingDirectory; m_unicodeEnvironmentBlock = unicodeEnvironmentBlock; m_standardInputEncoding = standardInputEncoding; m_standardErrorEncoding = standardErrorEncoding; m_errorDataReceived = errorDataReceived; m_standardOutputEncoding = standardOutputEncoding; m_outputDataReceived = outputDataReceived; m_processExitingAsync = processExitingAsync; m_processExited = processExited; m_timeout = timeout; m_disableConHostSharing = disableConHostSharing; m_containerConfiguration = containerConfiguration; m_setJobBreakawayOk = setJobBreakawayOk; m_createJobObjectForCurrentProcess = createJobObjectForCurrentProcess; if (m_workingDirectory != null && m_workingDirectory.Length == 0) { m_workingDirectory = Directory.GetCurrentDirectory(); } m_loggingContext = loggingContext; m_timeoutDumpDirectory = timeoutDumpDirectory; }
/// <summary> /// Creates a pipe reader. /// </summary> public static IAsyncPipeReader CreateNonDefaultPipeReader( NamedPipeServerStream pipeStream, StreamDataReceived callback, Encoding encoding, int bufferSize) { if (GetKind() == Kind.Pipeline) { #if NET_COREAPP_60 return(new PipelineAsyncPipeReader(pipeStream, callback, encoding)); #endif } // Fall back to use StreamReader based one. return(new StreamAsyncPipeReader(pipeStream, callback, encoding, bufferSize)); }
public void Event_StreamDataReceived(BoltConnection connection, UdpStreamData streamData) { INetworkInterfaceConnection interfaceConnection = FindInterfaceConnection(connection); if (interfaceConnection == null) { Log.Error($"[PhotonNetworkInterface] Received stream data from an unknown connection: {connection}."); return; } IStreamChannel streamChannel = FindStreamChannel(streamData.Channel); if (streamChannel == null) { Log.Error($"[PhotonNetworkInterface] Received stream data from an unknown channel '{streamData.Channel}'."); return; } Log.Info(LogChannel, "[PhotonNetworkInterface] Incoming stream data received: (length)" + streamData.Data.Length); StreamDataReceived?.Invoke(streamData.Data, streamChannel, interfaceConnection); }
public void Start() { Contract.Assume(!m_processStarted); Encoding reportEncoding = Encoding.Unicode; SafeFileHandle childHandle = null; DetouredProcess detouredProcess = m_detouredProcess; using (m_reportReaderSemaphore.AcquireSemaphore()) { SafeFileHandle reportHandle; try { Pipes.CreateInheritablePipe( Pipes.PipeInheritance.InheritWrite, Pipes.PipeFlags.ReadSideAsync, readHandle: out reportHandle, writeHandle: out childHandle); var setup = new FileAccessSetup { ReportPath = "#" + childHandle.DangerousGetHandle().ToInt64(), DllNameX64 = s_binaryPaths.DllNameX64, DllNameX86 = s_binaryPaths.DllNameX86, }; bool debugFlagsMatch = true; ArraySegment <byte> manifestBytes = new ArraySegment <byte>(); if (m_fileAccessManifest != null) { manifestBytes = m_fileAccessManifest.GetPayloadBytes(setup, FileAccessManifestStream, m_timeoutMins, ref debugFlagsMatch); } if (!debugFlagsMatch) { throw new BuildXLException("Mismatching build type for BuildXL and DetoursServices.dll."); } m_standardInputTcs = TaskSourceSlim.Create <bool>(); detouredProcess.Start( s_payloadGuid, manifestBytes, childHandle, s_binaryPaths.DllNameX64, s_binaryPaths.DllNameX86); // At this point, we believe calling 'kill' will result in an eventual callback for job teardown. // This knowledge is significant for ensuring correct cleanup if we did vs. did not start a process; // if started, we expect teardown to happen eventually and clean everything up. m_processStarted = true; ProcessId = detouredProcess.GetProcessId(); m_processIdListener?.Invoke(ProcessId); } finally { // release memory m_fileAccessManifest = null; // Note that in the success path, childHandle should already be closed (by Start). if (childHandle != null && !childHandle.IsInvalid) { childHandle.Dispose(); } } var reportFile = AsyncFileFactory.CreateAsyncFile( reportHandle, FileDesiredAccess.GenericRead, ownsHandle: true, kind: FileKind.Pipe); StreamDataReceived reportLineReceivedCallback = m_reports == null ? (StreamDataReceived)null : ReportLineReceived; m_reportReader = new AsyncPipeReader(reportFile, reportLineReceivedCallback, reportEncoding, m_bufferSize); m_reportReader.BeginReadLine(); } // don't wait, we want feeding in of standard input to happen asynchronously Analysis.IgnoreResult(FeedStandardInputAsync(detouredProcess, m_standardInputReader, m_standardInputTcs)); }
public void Start() { Contract.Assume(!m_processStarted); Encoding reportEncoding = Encoding.Unicode; SafeFileHandle childHandle = null; DetouredProcess detouredProcess = m_detouredProcess; bool useNonDefaultPipeReader = PipeReaderFactory.GetKind() != PipeReaderFactory.Kind.Default; using (m_reportReaderSemaphore.AcquireSemaphore()) { NamedPipeServerStream pipeStream = null; SafeFileHandle reportHandle = null; try { if (useNonDefaultPipeReader) { pipeStream = Pipes.CreateNamedPipeServerStream( PipeDirection.In, PipeOptions.Asynchronous, PipeOptions.None, out childHandle); } else { Pipes.CreateInheritablePipe( Pipes.PipeInheritance.InheritWrite, Pipes.PipeFlags.ReadSideAsync, readHandle: out reportHandle, writeHandle: out childHandle); } var setup = new FileAccessSetup { ReportPath = "#" + childHandle.DangerousGetHandle().ToInt64(), DllNameX64 = s_binaryPaths.DllNameX64, DllNameX86 = s_binaryPaths.DllNameX86, }; bool debugFlagsMatch = true; ArraySegment <byte> manifestBytes = new ArraySegment <byte>(); if (m_fileAccessManifest != null) { manifestBytes = m_fileAccessManifest.GetPayloadBytes(m_loggingContext, setup, FileAccessManifestStream, m_timeoutMins, ref debugFlagsMatch); } if (!debugFlagsMatch) { throw new BuildXLException("Mismatching build type for BuildXL and DetoursServices.dll."); } m_standardInputTcs = TaskSourceSlim.Create <bool>(); detouredProcess.Start( s_payloadGuid, manifestBytes, childHandle, s_binaryPaths.DllNameX64, s_binaryPaths.DllNameX86); // At this point, we believe calling 'kill' will result in an eventual callback for job teardown. // This knowledge is significant for ensuring correct cleanup if we did vs. did not start a process; // if started, we expect teardown to happen eventually and clean everything up. m_processStarted = true; ProcessId = detouredProcess.GetProcessId(); } catch (AccessViolationException) { int ramPercent = 0, availableRamMb = 0, availablePageFileMb = 0, totalPageFileMb = 0; MEMORYSTATUSEX memoryStatusEx = new MEMORYSTATUSEX(); if (GlobalMemoryStatusEx(memoryStatusEx)) { ramPercent = (int)memoryStatusEx.dwMemoryLoad; availableRamMb = new FileSize(memoryStatusEx.ullAvailPhys).MB; availablePageFileMb = new FileSize(memoryStatusEx.ullAvailPageFile).MB; totalPageFileMb = new FileSize(memoryStatusEx.ullTotalPageFile).MB; } string memUsage = $"RamPercent: {ramPercent}, AvailableRamMb: {availableRamMb}, AvailablePageFileMb: {availablePageFileMb}, TotalPageFileMb: {totalPageFileMb}"; Native.Tracing.Logger.Log.DetouredProcessAccessViolationException(m_loggingContext, (m_reports?.PipDescription ?? "") + " - " + memUsage); throw; } finally { // release memory m_fileAccessManifest = null; // Note that in the success path, childHandle should already be closed (by Start). if (childHandle != null && !childHandle.IsInvalid) { childHandle.Dispose(); } } StreamDataReceived reportLineReceivedCallback = m_reports == null ? null : ReportLineReceived; if (useNonDefaultPipeReader) { m_reportReader = PipeReaderFactory.CreateNonDefaultPipeReader( pipeStream, message => reportLineReceivedCallback(message), reportEncoding, m_bufferSize); } else { var reportFile = AsyncFileFactory.CreateAsyncFile( reportHandle, FileDesiredAccess.GenericRead, ownsHandle: true, kind: FileKind.Pipe); m_reportReader = new AsyncPipeReader( reportFile, reportLineReceivedCallback, reportEncoding, m_bufferSize, numOfRetriesOnCancel: m_numRetriesPipeReadOnCancel, debugPipeReporter: new AsyncPipeReader.DebugReporter(errorMsg => DebugPipeConnection($"ReportReader: {errorMsg}"))); } m_reportReader.BeginReadLine(); } // don't wait, we want feeding in of standard input to happen asynchronously Analysis.IgnoreResult(FeedStandardInputAsync(detouredProcess, m_standardInputReader, m_standardInputTcs)); }