Пример #1
0
        private async Task <OperationResult <ChannelState> > WriteWithTimeoutAsync(AsynchronousWritingOperation writingOperation, long length, TimeSpan timeout)
        {
            ThrowIfDisposed();

            bool gainedExclusiveAccess = false;

            try
            {
                var status = await AsyncHelper.GetTaskForWaitHandle(_exclusiveAccessSemaphore, timeout);

                if (status != OperationStatus.Completed)
                {
                    return(new OperationResult <ChannelState>(status, null));
                }

                gainedExclusiveAccess = true;

                return(await WriteAndSetEventsAsync(writingOperation, length));
            }
            finally
            {
                if (gainedExclusiveAccess)
                {
                    _exclusiveAccessSemaphore.Release();
                }
            }
        }
Пример #2
0
        public async Task <OperationResult <ChannelState> > WriteAsync(AsynchronousWritingOperation writingOperation, long length)
        {
            var header = Header.Read(_headerView);

            var allocationResult = AllocateSpaceFromFreeList(length, ref header);

            if (allocationResult.Status != OperationStatus.Completed)
            {
                return(new OperationResult <ChannelState>(allocationResult.Status, new ChannelState(header)));
            }

            var newNodePosition = allocationResult.Data;

            if (newNodePosition < 0)
            {
                if (header.TotalSpace + _sizeOfNode + length > Capacity)
                {
                    return(new OperationResult <ChannelState>(OperationStatus.OutOfSpace, new ChannelState(header)));
                }

                newNodePosition = header.TotalSpace;
            }

            return(await WriteNodeAndCommitAsync(newNodePosition, length, writingOperation, header));
        }
Пример #3
0
        private async Task <OperationResult <ChannelState> > WriteAndSetEventsAsync(AsynchronousWritingOperation writingOperation, long length)
        {
            var result = await((WriterMemoryManager)_memoryManager).WriteAsync(writingOperation, length);

            var channelState = result.Data;

            if (channelState != null && channelState.MessagesCount > 0)
            {
                _noMessagesEvent.Reset();

                _hasMessagesEvent.Set();
            }

            return(result);
        }
Пример #4
0
        private async Task <OperationResult <ChannelState> > WriteNodeAndCommitAsync(long newNodeOffset, long length, AsynchronousWritingOperation writingOperation, Header header)
        {
            var status = await writingOperation.WriteAsync(_file, newNodeOffset + _sizeOfNode, length);

            if (status != OperationStatus.RequestedLengthIsGreaterThanLogicalAddressSpace && status != OperationStatus.RequestedLengthIsGreaterThanVirtualAddressSpace)
            {
                if (status == OperationStatus.Cancelled || status == OperationStatus.DelegateFailed)
                {
                    ReturnSpaceToFreeList(newNodeOffset, length, ref header);
                }
                else
                {
                    var newNode = new Node(-1, length);

                    Node.Write(_file, newNodeOffset, ref newNode);

                    if (header.TailNode >= 0)
                    {
                        using (var tailView = _file.CreateViewAccessor(header.TailNode, _sizeOfNode))
                        {
                            var tail = Node.Read(tailView);

                            tail.Next = newNodeOffset;

                            Node.Write(tailView, ref tail);
                        }
                    }

                    header.TailNode = newNodeOffset;

                    if (header.HeadNode < 0)
                    {
                        header.HeadNode = newNodeOffset;
                    }

                    var allocated = (newNodeOffset + _sizeOfNode + length) - header.TotalSpace;

                    if (allocated > 0)
                    {
                        header.TotalSpace += allocated;
                    }

                    header.ActiveNodes += 1;
                }

                Header.Write(_headerView, ref header);
            }

            return(new OperationResult <ChannelState>(status, new ChannelState(header)));
        }