Skip to content

Commit 678d69a

Browse files
SoundStreamPlayer: Fix potential unsoundness
&mut existing and raw pointer access at the same time is unsound.
1 parent 3b3f684 commit 678d69a

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

src/audio/sound_stream.rs

+16-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use {
44
ffi::audio::*,
55
system::{Time, Vector3f},
66
},
7-
std::{os::raw::c_void, panic, ptr::NonNull},
7+
std::{marker::PhantomData, os::raw::c_void, panic, ptr::NonNull},
88
};
99

1010
/// Trait for streamed audio sources.
@@ -29,7 +29,12 @@ pub trait SoundStream: Send {
2929
#[derive(Debug)]
3030
pub struct SoundStreamPlayer<'a, S: SoundStream + 'a> {
3131
sf_sound_stream: NonNull<sfSoundStream>,
32-
stream: &'a mut S,
32+
/// We need to hold a raw pointer instead of a reference, since
33+
/// we send it to another thread, violating `&mut` rules.
34+
///
35+
/// Not sure if `NonNull` can be used to be honest. Not gonna risk it.
36+
stream: *mut S,
37+
_borrow: PhantomData<&'a mut S>,
3338
}
3439

3540
unsafe extern "C" fn get_data_callback<S: SoundStream>(
@@ -73,19 +78,22 @@ unsafe extern "C" fn seek_callback<S: SoundStream>(
7378
impl<'a, S: SoundStream> SoundStreamPlayer<'a, S> {
7479
/// Create a new `SoundStreamPlayer` with the specified [`SoundStream`].
7580
pub fn new(sound_stream: &'a mut S) -> Self {
76-
SoundStreamPlayer {
81+
let channel_count = sound_stream.channel_count();
82+
let sample_rate = sound_stream.sample_rate();
83+
let sound_stream: *mut S = sound_stream;
84+
Self {
7785
sf_sound_stream: unsafe {
78-
let ptr: *mut S = sound_stream;
7986
NonNull::new(sfSoundStream_create(
8087
Some(get_data_callback::<S>),
8188
Some(seek_callback::<S>),
82-
sound_stream.channel_count(),
83-
sound_stream.sample_rate(),
84-
ptr.cast(),
89+
channel_count,
90+
sample_rate,
91+
sound_stream.cast(),
8592
))
8693
.expect("Failed to create SoundStreamPlayer")
8794
},
8895
stream: sound_stream,
96+
_borrow: PhantomData,
8997
}
9098
}
9199
/// Start or resume playing the audio stream.
@@ -149,8 +157,8 @@ impl<'a, S: SoundStream> SoundStreamPlayer<'a, S> {
149157
pub fn stop(&mut self) -> &mut S {
150158
unsafe {
151159
sfSoundStream_stop(self.sf_sound_stream.as_ptr());
160+
&mut *self.stream
152161
}
153-
self.stream
154162
}
155163
/// Get the current playing position, from the beginning of the stream
156164
#[must_use]

0 commit comments

Comments
 (0)