From 33d8896279f5781ee7b54772864eb8be4d9d033c Mon Sep 17 00:00:00 2001 From: Nagata Parama Aptana <61454123+lifers@users.noreply.github.com> Date: Mon, 12 Aug 2024 21:17:44 -0400 Subject: [PATCH] use cast to *mut Array Assuming we have an exclusive access to the array --- crates/libs/core/src/event.rs | 59 ++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/crates/libs/core/src/event.rs b/crates/libs/core/src/event.rs index d07fb14836..a0dc3a5936 100644 --- a/crates/libs/core/src/event.rs +++ b/crates/libs/core/src/event.rs @@ -3,7 +3,7 @@ use core::ffi::c_void; use core::marker::PhantomData; use core::mem::{size_of, transmute_copy}; use core::ptr::null_mut; -use std::sync::{Mutex, RwLock}; +use std::sync::Mutex; /// A type that you can use to declare and implement an event of a specified delegate type. /// @@ -12,7 +12,7 @@ use std::sync::{Mutex, RwLock}; pub struct Event { swap: Mutex<()>, change: Mutex<()>, - delegates: RwLock>, + delegates: Array, } impl Default for Event { @@ -25,7 +25,7 @@ impl Event { /// Creates a new, empty `Event`. pub fn new() -> Self { Self { - delegates: RwLock::new(Array::new()), + delegates: Array::new(), swap: Mutex::default(), change: Mutex::default(), } @@ -36,19 +36,19 @@ impl Event { let mut _lock_free_drop = Array::new(); Ok({ let _change_lock = self.change.lock().unwrap(); - let delegate_array = self.delegates.read().unwrap(); - let mut new_delegates = Array::with_capacity(delegate_array.len() + 1)?; - for delegate in delegate_array.as_slice() { + let mut new_delegates = Array::with_capacity(self.delegates.len() + 1)?; + for delegate in self.delegates.as_slice() { new_delegates.push(delegate.clone()); } - drop(delegate_array); let delegate = Delegate::new(delegate)?; let token = delegate.to_token(); new_delegates.push(delegate); let _swap_lock = self.swap.lock().unwrap(); - let mut delegate_array = self.delegates.write().unwrap(); - _lock_free_drop = delegate_array.swap(new_delegates); + // Safety: we have exclusive access to self.delegates at this point + _lock_free_drop = unsafe { + Array::swap(core::ptr::addr_of!(self.delegates) as *mut _, new_delegates) + }; token }) } @@ -58,18 +58,17 @@ impl Event { let mut _lock_free_drop = Array::new(); { let _change_lock = self.change.lock().unwrap(); - let delegate_array = self.delegates.read().unwrap(); - if delegate_array.is_empty() { + if self.delegates.is_empty() { return Ok(()); } - let mut capacity = delegate_array.len() - 1; + let mut capacity = self.delegates.len() - 1; let mut new_delegates = Array::new(); let mut removed = false; if capacity == 0 { - removed = delegate_array.as_slice()[0].to_token() == token; + removed = self.delegates.as_slice()[0].to_token() == token; } else { new_delegates = Array::with_capacity(capacity)?; - for delegate in delegate_array.as_slice() { + for delegate in self.delegates.as_slice() { if !removed && delegate.to_token() == token { removed = true; continue; @@ -81,11 +80,12 @@ impl Event { capacity -= 1; } } - drop(delegate_array); if removed { let _swap_lock = self.swap.lock().unwrap(); - let mut delegate_array = self.delegates.write().unwrap(); - _lock_free_drop = delegate_array.swap(new_delegates); + // Safety: we have exclusive access to self.delegates at this point + _lock_free_drop = unsafe { + Array::swap(core::ptr::addr_of!(self.delegates) as *mut _, new_delegates) + }; } } Ok(()) @@ -93,18 +93,16 @@ impl Event { /// Clears the event, removing all delegates. pub fn clear(&self) { - let mut _lock_free_drop = Array::new(); + let mut _lock_free_drop = Array::::new(); { let _change_lock = self.change.lock().unwrap(); - { - let delegate_array = self.delegates.read().unwrap(); - if delegate_array.is_empty() { - return; - } + if self.delegates.is_empty() { + return; } let _swap_lock = self.swap.lock().unwrap(); - let mut delegate_array = self.delegates.write().unwrap(); - _lock_free_drop = delegate_array.swap(Array::new()); + // Safety: we have exclusive access to self.delegates at this point + _lock_free_drop = + unsafe { Array::swap(core::ptr::addr_of!(self.delegates) as *mut _, Array::new()) }; } } @@ -112,7 +110,7 @@ impl Event { pub fn call Result<()>>(&self, mut callback: F) -> Result<()> { let lock_free_calls = { let _swap_lock = self.swap.lock().unwrap(); - self.delegates.read().unwrap().clone() + self.delegates.clone() }; for delegate in lock_free_calls.as_slice() { if let Err(error) = delegate.call(&mut callback) { @@ -159,9 +157,12 @@ impl Array { } /// Swaps the contents of two `Array` objects. - fn swap(&mut self, mut other: Self) -> Self { - unsafe { core::ptr::swap(&mut self.buffer, &mut other.buffer) }; - core::mem::swap(&mut self.len, &mut other.len); + /// # Safety + /// - `current` and `other` must be valid pointers to `Array` objects. + /// - Caller must ensure that they have exclusive access to `current` and `other`. + unsafe fn swap(current: *mut Self, mut other: Self) -> Self { + core::mem::swap(&mut (*current).buffer, &mut other.buffer); + core::ptr::swap(&mut (*current).len, &mut other.len); other }