]> Repositorios git - scryer-prolog.git/commitdiff
detect and prevent² concurrent AtomTable use
authorBennet Bleßmann <[email protected]>
Thu, 27 Jul 2023 21:35:57 +0000 (23:35 +0200)
committerBennet Bleßmann <[email protected]>
Thu, 27 Jul 2023 21:37:03 +0000 (23:37 +0200)
²in the case of `#[cfg(not(test))]` there is still a toctou race as I am not sufficently familiar with Atomics

src/atom_table.rs

index b925273aea93ebbaf70c6cc4c3eace07a16bdec3..9f4801397c1fa70305628727dd8313ac8d502e59 100644 (file)
@@ -54,7 +54,12 @@ static mut ATOM_TABLE_BUF_BASE: *const u8 = ptr::null_mut();
 #[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;
     });
 }
 
@@ -66,6 +71,11 @@ pub(crate) fn get_atom_tbl_buf_base() -> *const u8 {
 #[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;
     }
 }
@@ -75,6 +85,13 @@ pub(crate) fn get_atom_tbl_buf_base() -> *const u8 {
     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 {
@@ -241,6 +258,7 @@ pub struct AtomTable {
 
 impl Drop for AtomTable {
     fn drop(&mut self) {
+        set_atom_tbl_buf_base(ptr::null());
         self.block.deallocate();
     }
 }