Esempio n. 1
0
        Task ISocketOutput.WriteAsync(ArraySegment <byte> buffer, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                _connection.Abort();
                _cancelled = true;
                return(TaskUtilities.GetCancelledTask(cancellationToken));
            }
            else if (_cancelled)
            {
                return(TaskUtilities.CompletedTask);
            }

            return(WriteAsync(buffer, cancellationToken));
        }
Esempio n. 2
0
        private Task ValidateState(CancellationToken cancellationToken)
        {
            switch (_state)
            {
            case FrameStreamState.Open:
                if (cancellationToken.IsCancellationRequested)
                {
                    return(TaskUtilities.GetCancelledTask(cancellationToken));
                }
                break;

            case FrameStreamState.Closed:
                throw new ObjectDisposedException(nameof(FrameResponseStream));

            case FrameStreamState.Aborted:
                if (cancellationToken.IsCancellationRequested)
                {
                    // Aborted state only throws on write if cancellationToken requests it
                    return(TaskUtilities.GetCancelledTask(cancellationToken));
                }
                break;
            }
            return(null);
        }
Esempio n. 3
0
        public Task WriteAsync(
            ArraySegment <byte> buffer,
            CancellationToken cancellationToken,
            bool socketShutdownSend = false,
            bool socketDisconnect   = false,
            bool isSync             = false)
        {
            TaskCompletionSource <object> tcs = null;
            var scheduleWrite = false;

            lock (_contextLock)
            {
                if (_socket.IsClosed)
                {
                    Service.Logger.Log(_lastWriteError);
                    return(TaskUtilities.CompletedTask);
                }

                if (buffer.Count > 0)
                {
                    var tail = ProducingStart();
                    if (tail.IsDefault)
                    {
                        return(TaskUtilities.CompletedTask);
                    }

                    tail.CopyFrom(buffer);

                    // We do our own accounting below
                    ProducingCompleteNoPreComplete(tail);
                }

                if (_nextWriteContext == null)
                {
                    if (_writeContextPool.Count > 0)
                    {
                        _nextWriteContext = _writeContextPool.Dequeue();
                    }
                    else
                    {
                        _nextWriteContext = new WriteContext(this);
                    }
                }

                if (socketShutdownSend)
                {
                    _nextWriteContext.SocketShutdownSend = true;
                }
                if (socketDisconnect)
                {
                    _nextWriteContext.SocketDisconnect = true;
                }

                if (_lastWriteError == null &&
                    _tasksPending.Count == 0 &&
                    _numBytesPreCompleted + buffer.Count <= _maxBytesPreCompleted)
                {
                    // Complete the write task immediately if all previous write tasks have been completed,
                    // the buffers haven't grown too large, and the last write to the socket succeeded.
                    _numBytesPreCompleted += buffer.Count;
                }
                else
                {
                    if (cancellationToken.CanBeCanceled)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            _connection.Abort();
                            _cancelled = true;
                            return(TaskUtilities.GetCancelledTask(cancellationToken));
                        }
                        else
                        {
                            // immediate write, which is not eligable for instant completion above
                            tcs = new TaskCompletionSource <object>();
                            _tasksPending.Enqueue(new WaitingTask()
                            {
                                CancellationToken        = cancellationToken,
                                CancellationRegistration = cancellationToken.Register(_connectionCancellation, this),
                                BytesToWrite             = buffer.Count,
                                CompletionSource         = tcs
                            });
                        }
                    }
                    else
                    {
                        tcs = new TaskCompletionSource <object>();
                        _tasksPending.Enqueue(new WaitingTask()
                        {
                            IsSync           = isSync,
                            BytesToWrite     = buffer.Count,
                            CompletionSource = tcs
                        });
                    }
                }

                if (!_postingWrite && _ongoingWrites < _maxPendingWrites)
                {
                    _postingWrite = true;
                    _ongoingWrites++;
                    scheduleWrite = true;
                }
            }

            if (scheduleWrite)
            {
                ScheduleWrite();
            }

            // Return TaskCompletionSource's Task if set, otherwise completed Task
            return(tcs?.Task ?? TaskUtilities.CompletedTask);
        }