#[cfg(test)]
fn set_atom_tbl_buf_base(ptr: *const u8) {
ATOM_TABLE_BUF_BASE.with(|atom_table_buf_base| {
- *atom_table_buf_base.borrow_mut() = ptr;
+ let mut borrow = atom_table_buf_base.borrow_mut();
+ assert!(
+ borrow.is_null() || ptr.is_null(),
+ "Overwriting atom table base pointer!"
+ );
+ *borrow = ptr;
});
}
#[cfg(not(test))]
fn set_atom_tbl_buf_base(ptr: *const u8) {
unsafe {
+ // FIXME: to prevent a toctou race-condition an atomic compare_exchange or a global lock should be used
+ assert!(
+ ATOM_TABLE_BUF_BASE.is_null() || ptr.is_null(),
+ "Overwriting atom table base pointer!"
+ );
ATOM_TABLE_BUF_BASE = ptr;
}
}
unsafe { ATOM_TABLE_BUF_BASE }
}
+#[test]
+#[should_panic(expected = "Overwriting atom table base pointer!")]
+fn atomtable_is_not_concurrency_safe() {
+ let table_a = AtomTable::new();
+ let table_b = AtomTable::new();
+}
+
impl RawBlockTraits for AtomTable {
#[inline]
fn init_size() -> usize {
impl Drop for AtomTable {
fn drop(&mut self) {
+ set_atom_tbl_buf_base(ptr::null());
self.block.deallocate();
}
}