1
0
mirror of https://github.com/bspeice/aeron-rs synced 2024-12-22 05:48:10 -05:00

Struct overlay, handle negative offsets

This commit is contained in:
Bradlee Speice 2019-10-04 20:26:15 -04:00
parent a40a71d4a8
commit 818d2ad821

View File

@ -25,23 +25,24 @@ impl<'a> AtomicBuffer<'a> {
AtomicBuffer { buffer } AtomicBuffer { buffer }
} }
fn bounds_check(&self, offset: IndexT, size: usize) -> Result<()> { #[allow(clippy::cast_ptr_alignment)]
if self.buffer.len() - (offset as usize) < size { fn overlay<T>(&self, offset: IndexT) -> Result<&T>
where
T: Sized,
{
if offset < 0 || self.buffer.len() - (offset as usize) < size_of::<T>() {
Err(AeronError::OutOfBounds) Err(AeronError::OutOfBounds)
} else { } else {
Ok(()) let offset_ptr = unsafe { self.buffer.as_ptr().offset(offset as isize) };
let t: &T = unsafe { &*(offset_ptr as *const T) };
Ok(t)
} }
} }
/// Atomically fetch the current value at an offset, and increment by delta /// Atomically fetch the current value at an offset, and increment by delta
#[allow(clippy::cast_ptr_alignment)]
pub fn get_and_add_i64(&self, offset: IndexT, delta: i64) -> Result<i64> { pub fn get_and_add_i64(&self, offset: IndexT, delta: i64) -> Result<i64> {
self.bounds_check(offset, size_of::<AtomicI64>()).map(|_| { self.overlay::<AtomicI64>(offset)
let a: &AtomicI64 = .map(|a| a.fetch_add(delta, Ordering::SeqCst))
unsafe { &*(self.buffer.as_ptr().offset(offset as isize) as *const AtomicI64) };
println!("AtomicI64: {:p}", a);
a.fetch_add(delta, Ordering::SeqCst)
})
} }
} }
@ -112,4 +113,14 @@ mod tests {
Err(AeronError::OutOfBounds) Err(AeronError::OutOfBounds)
); );
} }
#[test]
fn negative_offset() {
let mut buf = [16, 0, 0, 0, 0, 0, 0, 0];
let atomic_buf = AtomicBuffer::wrap(&mut buf);
assert_eq!(
atomic_buf.get_and_add_i64(-1, 0),
Err(AeronError::OutOfBounds)
)
}
} }