示例#1
0
        private OperationResult <ChannelState> WriteWithTimeout(WritingOperation writingOperation, long length, TimeSpan timeout)
        {
            ThrowIfDisposed();

            bool gainedExclusiveAccess = false;

            try
            {
                gainedExclusiveAccess = _exclusiveAccessSemaphore.WaitOne(timeout);

                if (!gainedExclusiveAccess)
                {
                    return(new OperationResult <ChannelState>(OperationStatus.Timeout, null));
                }

                return(WriteAndSetEvents(writingOperation, length));
            }
            finally
            {
                if (gainedExclusiveAccess)
                {
                    _exclusiveAccessSemaphore.Release();
                }
            }
        }
示例#2
0
        public OperationResult <ChannelState> Write(WritingOperation 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(WriteNodeAndCommit(newNodePosition, length, writingOperation, ref header));
        }
示例#3
0
        private OperationResult <ChannelState> WriteAndSetEvents(WritingOperation writingOperation, long length)
        {
            var result = ((WriterMemoryManager)_memoryManager).Write(writingOperation, length);

            var channelState = result.Data;

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

                _hasMessagesEvent.Set();
            }

            return(result);
        }
示例#4
0
        private OperationResult <ChannelState> WriteWithCancellation(WritingOperation writingOperation, long length, CancellationToken cancellationToken, TimeSpan timeout)
        {
            if (!cancellationToken.CanBeCanceled)
            {
                return(WriteWithTimeout(writingOperation, length, timeout));
            }

            ThrowIfDisposed();

            bool gainedExclusiveAccess = false;

            try
            {
                var index = WaitHandle.WaitAny(new[] { cancellationToken.WaitHandle, _exclusiveAccessSemaphore }, timeout);

                if (index == 0)
                {
                    return(new OperationResult <ChannelState>(OperationStatus.Cancelled, null));
                }

                if (index == WaitHandle.WaitTimeout)
                {
                    return(new OperationResult <ChannelState>(OperationStatus.Timeout, null));
                }

                gainedExclusiveAccess = true;

                return(WriteAndSetEvents(writingOperation, length));
            }
            finally
            {
                if (gainedExclusiveAccess)
                {
                    _exclusiveAccessSemaphore.Release();
                }
            }
        }
示例#5
0
        private OperationResult <ChannelState> WriteNodeAndCommit(long newNodeOffset, long length, WritingOperation writingOperation, ref Header header)
        {
            var result = writingOperation.Write(_file, newNodeOffset + _sizeOfNode, length);

            if (result != OperationStatus.RequestedLengthIsGreaterThanLogicalAddressSpace && result != OperationStatus.RequestedLengthIsGreaterThanVirtualAddressSpace)
            {
                if (result == OperationStatus.Cancelled || result == 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>(result, new ChannelState(header)));
        }