public void ShouldLimitReadOfMessages() { const int msgLength = 16; var recordLength = RingBufferDescriptor.HeaderLength + msgLength; var alignedRecordLength = recordLength.AlignToMultipleOf(RingBufferDescriptor.RecordAlignment); const long head = 0L; const int headIndex = (int)head; _atomicLong.Read(Head).Returns(head); _atomicLong.VolatileRead(new IntPtr(headIndex)) .Returns(RingBufferDescriptor.MakeHeader(recordLength, MessageTypeId)); var counter = 0; MessageHandler h = (id, chunk) => counter++; var messagesRead = _ringBuffer.Read(h, 1); Assert.AreEqual(1, messagesRead); Assert.AreEqual(1, counter); Received.InOrder(() => { _buffer.ZeroMemory(headIndex, alignedRecordLength); _atomicLong.VolatileWrite(Head, head + alignedRecordLength); }); }
public int Read(MessageHandler handler, int messageProcessingLimit) { var messagesRead = 0; var head = _head.Read(); var bytesRead = 0; var headIndex = (int)head & _mask; var contiguousBlockLength = Capacity - headIndex; try { while ((bytesRead < contiguousBlockLength) && (messagesRead < messageProcessingLimit)) { var recordIndex = headIndex + bytesRead; var header = _buffer.GetAtomicLong(recordIndex).VolatileRead(); var recordLength = RecordLength(header); if (recordLength <= 0) { break; } bytesRead += recordLength.AlignToMultipleOf(RecordAlignment); var messageTypeId = MessageTypeId(header); if (PaddingMsgTypeId == messageTypeId) { continue; } ++messagesRead; unsafe { handler(messageTypeId, new ByteChunk(_buffer.RawBytes + recordIndex + HeaderLength, recordLength - HeaderLength)); } } } finally { if (bytesRead != 0) { _buffer.ZeroMemory(headIndex, bytesRead); _head.VolatileWrite(head + bytesRead); } } return(messagesRead); }