Skip to content

Commit c5150ae

Browse files
committed
Lazily read Header
- Fixes #3
1 parent 9964e7e commit c5150ae

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

src/telemetry.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ pub struct Header {
5757
///
5858
pub struct Blocking<'conn> {
5959
origin: *const c_void,
60-
header: Header,
6160
event_handle: HANDLE,
6261
phantom: PhantomData<&'conn Connection>,
6362
}
@@ -318,10 +317,15 @@ impl fmt::Debug for ValueHeader {
318317

319318
impl Header {
320319
fn latest_buffer(&self) -> (i32, ValueBuffer) {
321-
let mut latest_tick: i32 = 0;
322320
let mut buffer = self.buffers[0];
323-
324-
for b in self.buffers.iter() {
321+
let mut latest_tick = buffer.ticks;
322+
323+
for b in self
324+
.buffers
325+
.iter()
326+
.skip(1)
327+
.take((self.n_buffers - 1) as usize)
328+
{
325329
if b.ticks > latest_tick {
326330
buffer = *b;
327331
latest_tick = b.ticks;
@@ -519,7 +523,7 @@ impl Display for TelemetryError {
519523
impl Error for TelemetryError {}
520524

521525
impl<'conn> Blocking<'conn> {
522-
fn new(location: *const c_void, head: Header) -> std::io::Result<Self> {
526+
fn new(location: *const c_void) -> std::io::Result<Self> {
523527
let mut event_name: Vec<u16> = DATA_EVENT_NAME.encode_utf16().collect();
524528
event_name.push(0);
525529

@@ -536,12 +540,22 @@ impl<'conn> Blocking<'conn> {
536540

537541
Ok(Blocking {
538542
origin: location,
539-
header: head,
540543
event_handle: handle,
541544
phantom: PhantomData,
542545
})
543546
}
544547

548+
/// Get the data header
549+
///
550+
/// Reads the data header from the shared memory map and returns a copy of the header
551+
/// which can be used safely elsewhere.
552+
fn read_header(&self) -> Header {
553+
let raw_header = self.origin as *const Header;
554+
// SAFETY: This read CANNOT be done safely, since it is an unsynchronized clone of a struct
555+
// larger than AtomicUsize.
556+
unsafe { *raw_header }
557+
}
558+
545559
///
546560
/// Sample Telemetry Data
547561
///
@@ -581,7 +595,7 @@ impl<'conn> Blocking<'conn> {
581595
0x00 => {
582596
// OK
583597
ResetEvent(self.event_handle);
584-
self.header.telemetry(self.origin)
598+
self.read_header().telemetry(self.origin)
585599
}
586600
_ => Err(Box::new(TelemetryError::UNKNOWN(signal as u32))),
587601
}
@@ -653,6 +667,8 @@ impl Connection {
653667
/// which can be used safely elsewhere.
654668
fn read_header(&self) -> Header {
655669
let raw_header = self.location as *const Header;
670+
// SAFETY: This read CANNOT be done safely, since it is an unsynchronized clone of a struct
671+
// larger than AtomicUsize.
656672
unsafe { *raw_header }
657673
}
658674

@@ -727,7 +743,7 @@ impl Connection {
727743
/// # }
728744
/// ```
729745
pub fn blocking(&self) -> IOResult<Blocking<'_>> {
730-
Blocking::new(self.location, self.read_header())
746+
Blocking::new(self.location)
731747
}
732748
}
733749

0 commit comments

Comments
 (0)