fix graph and white background added
This commit is contained in:
@@ -49,52 +49,50 @@ class ShmRingReader:
|
||||
logger.debug("Closed SHM ring reader %s", self.name)
|
||||
|
||||
def pop_payload(self) -> bytes | None:
|
||||
"""Read next payload from ring, or `None` if no unread payload exists."""
|
||||
write_seq = self._read_u64(24)
|
||||
read_seq = self._read_u64(32)
|
||||
if read_seq >= write_seq:
|
||||
return None
|
||||
"""Read the next unread payload, or `None` once none remains."""
|
||||
while True:
|
||||
write_seq = self._read_u64(24)
|
||||
read_seq = self._read_u64(32)
|
||||
if read_seq >= write_seq:
|
||||
return None
|
||||
# As in the C++ pop, a lapped, torn or corrupt slot is skipped with the backlog
|
||||
# behind the newest payload, which is read next (latest-wins).
|
||||
resync = max(read_seq + 1, write_seq - 1)
|
||||
|
||||
index = read_seq % self.capacity
|
||||
slot_offset = HEADER.size + index * (SLOT_HEADER_SIZE + self.slot_size_bytes)
|
||||
index = read_seq % self.capacity
|
||||
slot_offset = HEADER.size + index * (SLOT_HEADER_SIZE + self.slot_size_bytes)
|
||||
|
||||
# Seqlock read mirroring the C++ pop: a slot is valid for read_seq R only if
|
||||
# its sequence equals R+1 and is unchanged across the payload copy (i.e. the
|
||||
# producer did not overwrite this slot mid-copy). Sequence and payload_size
|
||||
# are read first; the slot is only accepted after the re-read confirms both.
|
||||
sequence = self._read_u64(slot_offset + 8)
|
||||
if sequence != read_seq + 1:
|
||||
# Producer overwrote this slot before we read it. Resync to latest.
|
||||
logger.debug("Ring %s: slot lapped before read, resyncing to write_seq=%d", self.name, write_seq)
|
||||
atomics.advance(self._mmap, 32, write_seq)
|
||||
return None
|
||||
# Seqlock read mirroring the C++ pop: a slot is valid for read_seq R only if
|
||||
# its sequence equals R+1 and is unchanged across the payload copy (i.e. the
|
||||
# producer did not overwrite this slot mid-copy). Sequence and payload_size
|
||||
# are read first; the slot is only accepted after the re-read confirms both.
|
||||
if self._read_u64(slot_offset + 8) != read_seq + 1:
|
||||
logger.debug("Ring %s: slot lapped before read, resyncing to %d", self.name, resync)
|
||||
atomics.advance(self._mmap, 32, resync)
|
||||
continue
|
||||
|
||||
payload_size = self._read_u32(slot_offset)
|
||||
# Bound payload_size against the slot before slicing so a torn/garbage size
|
||||
# can never read out of the slot region; resync and skip on violation.
|
||||
if payload_size > self.slot_size_bytes:
|
||||
logger.debug(
|
||||
"Ring %s: payload_size %d exceeds slot %d, resyncing",
|
||||
self.name,
|
||||
payload_size,
|
||||
self.slot_size_bytes,
|
||||
)
|
||||
atomics.advance(self._mmap, 32, write_seq)
|
||||
return None
|
||||
payload_size = self._read_u32(slot_offset)
|
||||
# Bound payload_size against the slot before slicing so a torn/garbage size
|
||||
# can never read out of the slot region.
|
||||
if payload_size > self.slot_size_bytes:
|
||||
logger.debug("Ring %s: payload_size %d exceeds slot %d, resyncing to %d",
|
||||
self.name, payload_size, self.slot_size_bytes, resync)
|
||||
atomics.advance(self._mmap, 32, resync)
|
||||
continue
|
||||
|
||||
payload_offset = slot_offset + SLOT_HEADER_SIZE
|
||||
payload = bytes(self._mmap[payload_offset : payload_offset + payload_size])
|
||||
atomics.fence()
|
||||
payload_offset = slot_offset + SLOT_HEADER_SIZE
|
||||
payload = bytes(self._mmap[payload_offset : payload_offset + payload_size])
|
||||
atomics.fence()
|
||||
|
||||
# Re-read the slot sequence after the copy; if it changed, the producer
|
||||
# overwrote this slot mid-copy and the payload is torn — discard and resync.
|
||||
if self._read_u64(slot_offset + 8) != read_seq + 1:
|
||||
logger.debug("Ring %s: slot overwritten mid-copy, discarding torn payload", self.name)
|
||||
atomics.advance(self._mmap, 32, write_seq)
|
||||
return None
|
||||
# Re-read the slot sequence after the copy; if it changed, the producer
|
||||
# overwrote this slot mid-copy and the payload is torn.
|
||||
if self._read_u64(slot_offset + 8) != read_seq + 1:
|
||||
logger.debug("Ring %s: slot overwritten mid-copy, resyncing to %d", self.name, resync)
|
||||
atomics.advance(self._mmap, 32, resync)
|
||||
continue
|
||||
|
||||
atomics.advance(self._mmap, 32, read_seq + 1)
|
||||
return payload
|
||||
atomics.advance(self._mmap, 32, read_seq + 1)
|
||||
return payload
|
||||
|
||||
def pop_raw_collection(self) -> SweepCollection | None:
|
||||
"""Read next raw collection from ring."""
|
||||
|
||||
Reference in New Issue
Block a user