예제 #1
0
        public async Task SetResult_AfterOnCompleted_ResultAvailableAsynchronously()
        {
            var mrvts = new ManualResetValueTaskSource <int>();

            mrvts.Reset();
            mrvts.Reset();
            Assert.Equal(2, mrvts.Version);

            Assert.Equal(ValueTaskSourceStatus.Pending, mrvts.GetStatus(2));
            Assert.Throws <InvalidOperationException>(() => mrvts.GetResult(2));

            var onCompletedRan = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

            mrvts.OnCompleted(s => ((TaskCompletionSource)s).SetResult(), onCompletedRan, 2, ValueTaskSourceOnCompletedFlags.None);

            Assert.False(onCompletedRan.Task.IsCompleted);
            await Task.Delay(1);

            Assert.False(onCompletedRan.Task.IsCompleted);

            mrvts.SetResult(42);
            Assert.Equal(ValueTaskSourceStatus.Succeeded, mrvts.GetStatus(2));
            Assert.Equal(42, mrvts.GetResult(2));

            await onCompletedRan.Task;

            Assert.Equal(2, mrvts.Version);
        }
예제 #2
0
        public void SetResult_RunContinuationsAsynchronously_ContinuationInvokedAccordingly(bool runContinuationsAsynchronously)
        {
            var mres  = new ManualResetEventSlim();
            var mrvts = new ManualResetValueTaskSource <int>()
            {
                RunContinuationsAsynchronously = runContinuationsAsynchronously
            };

            for (short i = 0; i < 10; i++)
            {
                int threadId = Environment.CurrentManagedThreadId;
                mrvts.OnCompleted(
                    _ =>
                {
                    Assert.Equal(!runContinuationsAsynchronously, threadId == Environment.CurrentManagedThreadId);
                    mres.Set();
                },
                    null,
                    i,
                    ValueTaskSourceOnCompletedFlags.None);
                mrvts.SetResult(42);
                mres.Wait();
                mrvts.Reset();
                mres.Reset();
            }
        }
예제 #3
0
        public async Task SetResult_RunContinuationsAsynchronously_ContinuationInvokedAccordingly(bool runContinuationsAsynchronously)
        {
            var mrvts = new ManualResetValueTaskSource <int>()
            {
                RunContinuationsAsynchronously = runContinuationsAsynchronously
            };

            for (short i = 0; i < 10; i++)
            {
                var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

                var tl = new ThreadLocal <int> {
                    Value = 42
                };
                mrvts.OnCompleted(
                    _ =>
                {
                    Assert.Equal(!runContinuationsAsynchronously, tl.Value == 42);
                    tcs.SetResult();
                },
                    null,
                    i,
                    ValueTaskSourceOnCompletedFlags.None);
                mrvts.SetResult(42);
                mrvts.Reset();

                tl.Value = 0;

                await tcs.Task;
            }
        }
예제 #4
0
        /// <inheritdoc />
        public ValueTask <bool> MoveNextAsync()
        {
            var state = Atomic.Lock(ref _state);

            switch (state)
            {
            case _sInitial:
                _state = _sInitial;
                throw new InvalidOperationException("GetAsyncEnumerator was not called.");

            case _sEmitting:
                _tsAccepting.Reset();
                _state = _sAccepting;
                _tsEmitting.SetResult(true);
                return(_tsAccepting.Task);

            case _sAccepting:
                _state = _sAccepting;
                throw new InvalidOperationException("MoveNextAsync is not reentrant.");

            case _sFinal:
                Current = default;
                _state  = _sFinal;
                return(new(_atmbFinal.Task));

            default:
                _state = state;
                throw new Exception(state + "???");
            }
        }
        public void AccessAfterReset_Fails()
        {
            var mrvts = new ManualResetValueTaskSource <int>();

            mrvts.Reset();
            Assert.Throws <InvalidOperationException>(() => mrvts.GetResult(0));
            Assert.Throws <InvalidOperationException>(() => mrvts.GetStatus(0));
            Assert.Throws <InvalidOperationException>(() => mrvts.OnCompleted(_ => { }, new object(), 0, ValueTaskSourceOnCompletedFlags.None));
        }
예제 #6
0
        public void SetResult_BeforeOnCompleted_ResultAvailableSynchronously()
        {
            var mrvts = new ManualResetValueTaskSource <int>();

            mrvts.Reset();
            mrvts.Reset();
            Assert.Equal(2, mrvts.Version);

            mrvts.SetResult(42);

            Assert.Equal(ValueTaskSourceStatus.Succeeded, mrvts.GetStatus(2));
            Assert.Equal(42, mrvts.GetResult(2));

            var mres = new ManualResetEventSlim();

            mrvts.OnCompleted(s => ((ManualResetEventSlim)s).Set(), mres, 2, ValueTaskSourceOnCompletedFlags.None);
            mres.Wait();

            Assert.Equal(2, mrvts.Version);
        }
예제 #7
0
        public async Task SetResult_BeforeOnCompleted_ResultAvailableSynchronously()
        {
            var mrvts = new ManualResetValueTaskSource <int>();

            mrvts.Reset();
            mrvts.Reset();
            Assert.Equal(2, mrvts.Version);

            mrvts.SetResult(42);

            Assert.Equal(ValueTaskSourceStatus.Succeeded, mrvts.GetStatus(2));
            Assert.Equal(42, mrvts.GetResult(2));

            var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

            mrvts.OnCompleted(s => ((TaskCompletionSource)s).SetResult(), tcs, 2, ValueTaskSourceOnCompletedFlags.None);
            await tcs.Task;

            Assert.Equal(2, mrvts.Version);
        }
예제 #8
0
        public void SetException_BeforeOnCompleted_ResultAvailableSynchronously()
        {
            var mrvts = new ManualResetValueTaskSource <int>();

            mrvts.Reset();
            mrvts.Reset();
            Assert.Equal(2, mrvts.Version);

            var e = new FormatException();

            mrvts.SetException(e);

            Assert.Equal(ValueTaskSourceStatus.Faulted, mrvts.GetStatus(2));
            Assert.Same(e, Assert.Throws <FormatException>(() => mrvts.GetResult(2)));

            var mres = new ManualResetEventSlim();

            mrvts.OnCompleted(s => ((ManualResetEventSlim)s).Set(), mres, 2, ValueTaskSourceOnCompletedFlags.None);
            mres.Wait();

            Assert.Equal(2, mrvts.Version);
        }
예제 #9
0
        public async Task SetException_BeforeOnCompleted_ResultAvailableSynchronously()
        {
            var mrvts = new ManualResetValueTaskSource <int>();

            mrvts.Reset();
            mrvts.Reset();
            Assert.Equal(2, mrvts.Version);

            var e = new FormatException();

            mrvts.SetException(e);

            Assert.Equal(ValueTaskSourceStatus.Faulted, mrvts.GetStatus(2));
            Assert.Same(e, Assert.Throws <FormatException>(() => mrvts.GetResult(2)));

            var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

            mrvts.OnCompleted(s => ((TaskCompletionSource)s).SetResult(), tcs, 2, ValueTaskSourceOnCompletedFlags.None);
            await tcs.Task;

            Assert.Equal(2, mrvts.Version);
        }
예제 #10
0
        public void SetTwice_Fails()
        {
            var mrvts = new ManualResetValueTaskSource <int>();

            mrvts.SetResult(42);
            Assert.Throws <InvalidOperationException>(() => mrvts.SetResult(42));
            Assert.Throws <InvalidOperationException>(() => mrvts.SetException(new Exception()));

            mrvts.Reset();
            mrvts.SetException(new Exception());
            Assert.Throws <InvalidOperationException>(() => mrvts.SetResult(42));
            Assert.Throws <InvalidOperationException>(() => mrvts.SetException(new Exception()));
        }
예제 #11
0
        public async Task ReuseInstanceWithResets_Success()
        {
            var mrvts = new ManualResetValueTaskSource <int>();

            for (short i = 42; i < 48; i++)
            {
                var ignored = Task.Delay(1).ContinueWith(_ => mrvts.SetResult(i));
                Assert.Equal(i, await new ValueTask <int>(mrvts, mrvts.Version));
                Assert.Equal(i, await new ValueTask <int>(mrvts, mrvts.Version)); // can use multiple times until it's reset

                mrvts.Reset();
            }
        }
예제 #12
0
    public void Initialize(Http3StreamContext context)
    {
        base.Initialize(context);

        InputRemaining = null;

        _context = context;

        _errorCodeFeature   = _context.ConnectionFeatures.GetRequiredFeature <IProtocolErrorCodeFeature>();
        _streamIdFeature    = _context.ConnectionFeatures.GetRequiredFeature <IStreamIdFeature>();
        _streamAbortFeature = _context.ConnectionFeatures.GetRequiredFeature <IStreamAbortFeature>();

        _appCompletedTaskSource.Reset();
        _isClosed = 0;
        _requestHeaderParsingState = default;
        _parsedPseudoHeaderFields  = default;
        _totalParsedHeaderSize     = 0;
        _isMethodConnect           = false;
        _completionState           = default;
        StreamTimeoutTicks         = 0;

        if (_frameWriter == null)
        {
            _frameWriter = new Http3FrameWriter(
                context.StreamContext,
                context.TimeoutControl,
                context.ServiceContext.ServerOptions.Limits.MinResponseDataRate,
                context.MemoryPool,
                context.ServiceContext.Log,
                _streamIdFeature,
                context.ClientPeerSettings,
                this);

            _http3Output = new Http3OutputProducer(
                _frameWriter,
                context.MemoryPool,
                this,
                context.ServiceContext.Log);
            Output          = _http3Output;
            RequestBodyPipe = CreateRequestBodyPipe(64 * 1024); // windowSize?
            QPackDecoder    = new QPackDecoder(_context.ServiceContext.ServerOptions.Limits.Http3.MaxRequestHeaderFieldSize);
        }
        else
        {
            _http3Output.StreamReset();
            RequestBodyPipe.Reset();
            QPackDecoder.Reset();
        }

        _frameWriter.Reset(context.Transport.Output, context.ConnectionId);
    }
예제 #13
0
    public override ManualResetValueTaskSource <object?> GetAwaitable()
    {
        if (_awaitable == null)
        {
            _awaitable = new ManualResetValueTaskSource <object?>();
        }
        else
        {
            Debug.Assert(_awaitable.GetStatus() == ValueTaskSourceStatus.Succeeded, "Previous awaitable should have been completed.");
            _awaitable.Reset();
        }

        return(_awaitable);
    }
        public async Task Reset_Success()
        {
            var source    = new ManualResetValueTaskSource <int>();
            var valueTask = new ValueTask <int>(source, source.Version);

            source.SetResult(10);
            var result = await valueTask;

            Assert.True(result == 10);
            source.Reset();
            var valueTask_1 = new ValueTask <int>(source, source.Version);

            source.SetResult(100);
            result = await valueTask_1;
            Assert.True(result == 100);
        }
예제 #15
0
        public IAsyncEnumerator <T> GetAsyncEnumerator(CancellationToken token)
        {
            if (token.IsCancellationRequested)
            {
                return(new LinxAsyncEnumerable.ThrowIterator <T>(new OperationCanceledException(token)));
            }

            var state = Atomic.Lock(ref _state);

            if (state != _sInitial)
            {
                _state = state;
                return(new CoroutineIterator <T>(this).GetAsyncEnumerator(token));
            }

            try
            {
                _tsAccepting = new();
                _tsEmitting  = new();
                _tsEmitting.Reset();
                _state = _sEmitting;
                Produce(token);
                if (token.CanBeCanceled)
                {
                    _ctr = token.Register(() => SetFinal(new OperationCanceledException(token)));
                }
                return(this);
            }
            catch (Exception ex)
            {
                _state        = Atomic.LockBit;
                Current       = default;
                _tsAccepting  = default;
                _tsEmitting   = default;
                _atmbFinal    = default;
                _atmbDisposed = default;
                _ctr          = default;
                _state        = _sFinal;
                _atmbFinal.SetException(ex);
                _atmbDisposed.SetResult();
                return(new LinxAsyncEnumerable.ThrowIterator <T>(ex));
            }
        }
        public async Task Reset_Failed()
        {
            var source    = new ManualResetValueTaskSource <int>();
            var valueTask = new ValueTask <int>(source, 0);

            source.SetResult(10);
            var result = await valueTask;

            Assert.True(result == 10);
            source.Reset();
            var valueTask_1 = new ValueTask <int>(source, 0);

            source.SetResult(100);
            var ex = await Assert.ThrowsAsync <InvalidOperationException>(async() =>
            {
                result = await valueTask_1;
            });

            Assert.True(ex is InvalidOperationException);
        }
예제 #17
0
        private ValueTask <bool> YieldAsync(T item)
        {
            var state = Atomic.Lock(ref _state);

            switch (state)
            {
            case _sAccepting:
                Current = item;
                _tsEmitting.Reset();
                _state = _sEmitting;
                _tsAccepting.SetResult(true);
                return(_tsEmitting.Task);

            case _sFinal:
                _state = _sFinal;
                return(new(false));

            default:
                _state = state;
                throw new InvalidOperationException(state + "???");
            }
        }
예제 #18
0
 public bool Return(ManualResetValueTaskSource <T> obj)
 {
     obj.Reset();
     return(true);
 }