Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make various types Send and Sync #331

Merged
merged 2 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/audio/capture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,15 @@ pub struct SoundRecorderDriver<'a, R: 'a> {
recorder: &'a mut R,
}

// SAFETY: An `sfCustomSoundRecorder` isn't tied to a particular thread, so it can be sent between
// threads safely.
unsafe impl<R: Send> Send for SoundRecorderDriver<'_, R> {}

// SAFETY: An `&SoundRecorderDriver` only allows access to methods which read the status of the
// driver, which is fine to do from multiple threads at once. Thus it is safe to pass
// `&SoundRecorderDriver` between threads.
unsafe impl<R: Sync> Sync for SoundRecorderDriver<'_, R> {}

unsafe extern "C" fn on_start_callback<R: SoundRecorder>(user_data: *mut c_void) -> bool {
let recorder: *mut R = user_data.cast();
unsafe { (*recorder).on_start() }
Expand Down Expand Up @@ -246,6 +255,16 @@ pub struct SoundBufferRecorder {
handle: NonNull<ffi::sfSoundBufferRecorder>,
}

// SAFETY: An `sfSoundBufferRecorder` isn't tied to a particular thread, so it can be sent between
// threads safely.
unsafe impl Send for SoundBufferRecorder {}

// SAFETY: An `&SoundBufferRecorder` only allows access to methods which read the status of the
// recorder, which is fine to do from multiple threads at once. Thus it is safe to pass
// `&SoundBufferRecorder` between threads.
unsafe impl Sync for SoundBufferRecorder {}


impl SoundBufferRecorder {
/// Create a new sound buffer recorder
///
Expand Down
7 changes: 7 additions & 0 deletions src/audio/music.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ pub struct Music<'src> {
_stream: PhantomData<&'src mut ()>,
}

// SAFETY: An `sfMusic` isn't tied to a particular thread, so it can be sent between threads safely.
unsafe impl Send for Music<'_> {}

// SAFETY: An `&Music` only allows access to methods which read the status of the music, which is
// fine to do from multiple threads at once. Thus it is safe to pass `&Music` between threads.
unsafe impl Sync for Music<'_> {}

/// Creating and opening
impl<'src> Music<'src> {
/// Create a new (empty) `Music`.
Expand Down
7 changes: 7 additions & 0 deletions src/audio/sound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ pub struct Sound<'buf> {
buffer: PhantomData<&'buf SoundBuffer>,
}

// SAFETY: An `sfSound` isn't tied to a particular thread, so it can be sent between threads safely.
unsafe impl Send for Sound<'_> {}

// SAFETY: An `&Sound` only allows access to methods which read the status of the sound, which is
// fine to do from multiple threads at once. Thus it is safe to pass `&Sound` between threads.
unsafe impl Sync for Sound<'_> {}

/// Creation
impl<'buf> Sound<'buf> {
/// Create a new `Sound`
Expand Down
9 changes: 9 additions & 0 deletions src/cpp/fbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ impl<T: ?Sized> std::fmt::Debug for FBox<T> {
}
}

// SAFETY: An `FBox` owns its contents, so it is safe to move between threads if and only if the
// contents is safe to move between threads. This matches the behaviour of `std::boxed::Box`.
unsafe impl <T: Send> Send for FBox<T> {}

// SAFETY: An `FBox` derefs to its contents, so it is safe to pass an `&FBox<T>` between threads if
// and only if it is safe to pass a reference to its contents between threads. This matches the
// behaviour of `std::boxed::Box`.
unsafe impl <T: Sync> Sync for FBox<T> {}

impl<T: ?Sized> FBox<T> {
pub(crate) fn new(ptr: *mut T) -> Option<Self> {
NonNull::new(ptr).map(FBox)
Expand Down