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(); } } }
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)); }
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); }
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))); }