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