Skip to content

Commit

Permalink
Make DispatchObject send + sync
Browse files Browse the repository at this point in the history
Should automatically enable send + sync for all types holding it
  • Loading branch information
pronebird committed Dec 19, 2024
1 parent 03e3882 commit 15cf6cd
Showing 1 changed file with 23 additions and 9 deletions.
32 changes: 23 additions & 9 deletions crates/dispatch2/src/object.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
//! Dispatch object definition.
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};

use super::{ffi::*, queue::Queue, utils::function_wrapper, QualityOfServiceClass};

/// Error returned by [DispatchObject::set_target_queue].
Expand All @@ -23,7 +28,7 @@ pub enum QualityOfServiceClassFloorError {
#[derive(Debug)]
pub struct DispatchObject<T> {
object: *mut T,
is_activated: bool,
is_activated: Arc<AtomicBool>,
}

impl<T> DispatchObject<T> {
Expand All @@ -35,7 +40,7 @@ impl<T> DispatchObject<T> {
pub unsafe fn new_owned(object: *mut T) -> Self {
Self {
object,
is_activated: false,
is_activated: Arc::new(AtomicBool::new(false)),
}
}

Expand All @@ -47,7 +52,7 @@ impl<T> DispatchObject<T> {
pub unsafe fn new_shared(object: *mut T) -> Self {
let result = Self {
object,
is_activated: false,
is_activated: Arc::new(AtomicBool::new(false)),
};

// Safety: We own a reference to the object.
Expand Down Expand Up @@ -80,7 +85,7 @@ impl<T> DispatchObject<T> {
///
/// - DispatchObject should be a queue or queue source.
pub unsafe fn set_target_queue(&self, queue: &Queue) -> Result<(), TargetQueueError> {
if self.is_activated {
if self.is_activated.load(Ordering::SeqCst) {
return Err(TargetQueueError::ObjectAlreadyActive);
}

Expand Down Expand Up @@ -120,12 +125,15 @@ impl<T> DispatchObject<T> {

/// Activate the object.
pub fn activate(&mut self) {
// Safety: object cannot be null.
unsafe {
dispatch_activate(self.as_raw().cast());
if let Ok(true) =
self.is_activated
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
{
// Safety: object cannot be null.
unsafe {
dispatch_activate(self.as_raw().cast());
}
}

self.is_activated = true;
}

/// Suspend the invocation of functions on the object.
Expand Down Expand Up @@ -169,3 +177,9 @@ impl<T> Drop for DispatchObject<T> {
}
}
}

// Safety: dispatch object can be safely moved between threads.
unsafe impl<T> Send for DispatchObject<T> {}

// Safety: dispatch object can be shared between threads.
unsafe impl<T> Sync for DispatchObject<T> {}

0 comments on commit 15cf6cd

Please sign in to comment.