private MsQuicStream StreamOpen( QUIC_STREAM_OPEN_FLAG flags) { if (NetEventSource.IsEnabled) { NetEventSource.Enter(this); } IntPtr streamPtr = IntPtr.Zero; QuicExceptionHelpers.ThrowIfFailed( MsQuicApi.Api.StreamOpenDelegate( _ptr, (uint)flags, MsQuicStream.NativeCallbackHandler, IntPtr.Zero, out streamPtr), "Failed to open stream to peer."); MsQuicStream stream = new MsQuicStream(this, flags, streamPtr, inbound: false); if (NetEventSource.IsEnabled) { NetEventSource.Exit(this); } return(stream); }
internal MsQuicStream(MsQuicConnection connection, QUIC_STREAM_OPEN_FLAG flags, IntPtr nativeObjPtr, bool inbound) { Debug.Assert(connection != null, "Connection null"); _ptr = nativeObjPtr; _sendResettableCompletionSource = new ResettableCompletionSource <uint>(); _receiveResettableCompletionSource = new ResettableCompletionSource <uint>(); SetCallbackHandler(); bool isBidirectional = !flags.HasFlag(QUIC_STREAM_OPEN_FLAG.UNIDIRECTIONAL); if (inbound) { _canRead = true; _canWrite = isBidirectional; _started = true; } else { _canRead = isBidirectional; _canWrite = true; StartLocalStream(); } }
private async ValueTask <ConnectionContext> StartStreamAsync(QUIC_STREAM_OPEN_FLAG flags) { var stream = StreamOpen(flags); await stream.StartAsync(); return(stream); }
// Creates a new MsQuicStream internal MsQuicStream(MsQuicConnection connection, QUIC_STREAM_OPEN_FLAG flags, IntPtr nativeObjPtr, bool inbound) { Debug.Assert(connection != null); _ptr = nativeObjPtr; if (inbound) { _started = StartState.Finished; _canWrite = !flags.HasFlag(QUIC_STREAM_OPEN_FLAG.UNIDIRECTIONAL); _canRead = true; } else { _started = StartState.None; _canWrite = true; _canRead = !flags.HasFlag(QUIC_STREAM_OPEN_FLAG.UNIDIRECTIONAL); } _sendResettableCompletionSource = new ResettableCompletionSource <uint>(); _receiveResettableCompletionSource = new ResettableCompletionSource <uint>(); _shutdownWriteResettableCompletionSource = new ResettableCompletionSource <uint>(); SetCallbackHandler(); }
public MsQuicStream StreamOpen( QUIC_STREAM_OPEN_FLAG flags) { var streamPtr = IntPtr.Zero; var status = _api.StreamOpenDelegate( _nativeObjPtr, (uint)flags, MsQuicStream.NativeCallbackHandler, IntPtr.Zero, out streamPtr); MsQuicStatusException.ThrowIfFailed(status); return(new MsQuicStream(_api, this, _context, flags, streamPtr)); }
private MsQuicStream StreamOpen( QUIC_STREAM_OPEN_FLAG flags) { IntPtr streamPtr = IntPtr.Zero; QuicExceptionHelpers.ThrowIfFailed( MsQuicApi.Api.StreamOpenDelegate( _ptr, (uint)flags, MsQuicStream.s_streamDelegate, IntPtr.Zero, out streamPtr), "Failed to open stream to peer."); return(new MsQuicStream(this, flags, streamPtr, inbound: false)); }
public MsQuicStream(MsQuicApi api, MsQuicConnection connection, MsQuicTransportContext context, QUIC_STREAM_OPEN_FLAG flags, IntPtr nativeObjPtr) { Debug.Assert(connection != null); Api = api; _nativeObjPtr = nativeObjPtr; _connection = connection; MemoryPool = context.Options.MemoryPoolFactory(); _log = context.Log; ConnectionClosed = _streamClosedTokenSource.Token; var maxReadBufferSize = context.Options.MaxReadBufferSize.Value; var maxWriteBufferSize = context.Options.MaxWriteBufferSize.Value; _resettableCompletion = new ResettableCompletionSource(this); // TODO should we allow these PipeScheduler to be configurable here? var inputOptions = new PipeOptions(MemoryPool, PipeScheduler.ThreadPool, PipeScheduler.Inline, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false); var outputOptions = new PipeOptions(MemoryPool, PipeScheduler.Inline, PipeScheduler.ThreadPool, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false); var pair = DuplexPipe.CreateConnectionPair(inputOptions, outputOptions); Features.Set <IQuicStreamFeature>(this); // TODO populate the ITlsConnectionFeature (requires client certs). Features.Set <ITlsConnectionFeature>(new FakeTlsConnectionFeature()); if (flags.HasFlag(QUIC_STREAM_OPEN_FLAG.UNIDIRECTIONAL)) { IsUnidirectional = true; } Transport = pair.Transport; Application = pair.Application; SetCallbackHandler(); _processingTask = ProcessSends(); }