Skip to content

Commit eeafe6f

Browse files
committed
sndio: avoid unsafe impl Send on InnerState
1 parent 2e0c63b commit eeafe6f

File tree

2 files changed

+18
-16
lines changed

2 files changed

+18
-16
lines changed

src/host/sndio/mod.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,16 @@ impl Iterator for Devices {
113113
}
114114
}
115115

116+
struct SioHdl(*mut sndio_sys::sio_hdl);
117+
118+
unsafe impl Send for SioHdl {}
119+
116120
/// The shared state between Device and Stream. Responsible for closing handle when dropped.
117121
struct InnerState {
118122
/// If device has been open with sio_open, contains a handle. Note that even though this is a
119123
/// pointer type and so doesn't follow Rust's borrowing rules, we should be careful not to copy
120124
/// it out because that may render Mutex<InnerState> ineffective in enforcing exclusive access.
121-
hdl: Option<*mut sndio_sys::sio_hdl>,
125+
hdl: Option<SioHdl>,
122126

123127
/// Buffer overrun/underrun behavior -- ignore/sync/error?
124128
behavior: BufferXrunBehavior,
@@ -159,8 +163,6 @@ struct OutputCallbacks {
159163
error_callback: Box<dyn FnMut(StreamError) + Send + 'static>,
160164
}
161165

162-
unsafe impl Send for InnerState {}
163-
164166
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
165167
enum Status {
166168
/// Initial state. No thread running. Device/Stream methods will start thread and change this
@@ -205,7 +207,7 @@ impl InnerState {
205207
if hdl.is_null() {
206208
return Err(SndioError::DeviceNotAvailable);
207209
}
208-
self.hdl = Some(hdl);
210+
self.hdl = Some(SioHdl(hdl));
209211

210212
let mut sample_rate_to_par = HashMap::new();
211213
for rate in SUPPORTED_SAMPLE_RATES {
@@ -267,7 +269,7 @@ impl InnerState {
267269
// will wait for playback data to be provided (using the sio_write()
268270
// function). Once enough data is queued to ensure that play buffers will
269271
// not underrun, actual playback is started automatically."
270-
sndio_sys::sio_start(self.hdl.unwrap()) // Unwrap OK because of check above
272+
sndio_sys::sio_start(self.hdl.as_ref().unwrap().0) // Unwrap OK because of check above
271273
};
272274
if status != 1 {
273275
return Err(backend_specific_error("failed to start stream"));
@@ -286,7 +288,7 @@ impl InnerState {
286288
// playback. If samples to play are queued but playback hasn't started yet then
287289
// playback is forced immediately; playback will actually stop once the buffer is
288290
// drained. In no case are samples in the play buffer discarded.
289-
sndio_sys::sio_stop(self.hdl.unwrap()) // Unwrap OK because of check above
291+
sndio_sys::sio_stop(self.hdl.as_ref().unwrap().0) // Unwrap OK because of check above
290292
};
291293
if status != 1 {
292294
return Err(backend_specific_error("error calling sio_stop"));
@@ -385,7 +387,7 @@ impl InnerState {
385387

386388
let status = unsafe {
387389
// Retrieve the actual parameters of the device.
388-
sndio_sys::sio_getpar(self.hdl.unwrap(), par as *mut _)
390+
sndio_sys::sio_getpar(self.hdl.as_ref().unwrap().0, par as *mut _)
389391
};
390392
if status != 1 {
391393
return Err(backend_specific_error(
@@ -439,7 +441,7 @@ impl InnerState {
439441
let status = unsafe {
440442
// Request the device using our parameters
441443
// unwrap OK because of the check at the top of this function.
442-
sndio_sys::sio_setpar(self.hdl.unwrap(), &mut newpar as *mut _)
444+
sndio_sys::sio_setpar(self.hdl.as_ref().unwrap().0, &mut newpar as *mut _)
443445
};
444446
if status != 1 {
445447
return Err(backend_specific_error("failed to set parameters with sio_setpar").into());
@@ -452,7 +454,7 @@ impl Drop for InnerState {
452454
fn drop(&mut self) {
453455
if let Some(hdl) = self.hdl.take() {
454456
unsafe {
455-
sndio_sys::sio_close(hdl);
457+
sndio_sys::sio_close(hdl.0);
456458
}
457459
}
458460
}

src/host/sndio/runner.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ pub(super) fn runner(inner_state_arc: Arc<Mutex<InnerState>>) {
114114
paused = false;
115115
}
116116
nfds = unsafe {
117-
sndio_sys::sio_nfds(inner_state.hdl.unwrap()) // Unwrap OK because of open call above
117+
sndio_sys::sio_nfds(inner_state.hdl.as_ref().unwrap().0) // Unwrap OK because of open call above
118118
};
119119
if nfds <= 0 {
120120
inner_state.error(backend_specific_error(format!(
@@ -133,7 +133,7 @@ pub(super) fn runner(inner_state_arc: Arc<Mutex<InnerState>>) {
133133
// Populate pollfd structs with sndio_sys::sio_pollfd
134134
nfds = unsafe {
135135
sndio_sys::sio_pollfd(
136-
inner_state.hdl.unwrap(), // Unwrap OK because of open call above
136+
inner_state.hdl.as_ref().unwrap().0, // Unwrap OK because of open call above
137137
pollfds.as_mut_ptr(),
138138
(libc::POLLOUT | libc::POLLIN) as i32,
139139
)
@@ -162,9 +162,9 @@ pub(super) fn runner(inner_state_arc: Arc<Mutex<InnerState>>) {
162162
{
163163
let mut inner_state = inner_state_arc.lock().unwrap();
164164
// Unwrap OK because of open call above
165-
revents =
166-
unsafe { sndio_sys::sio_revents(inner_state.hdl.unwrap(), pollfds.as_mut_ptr()) }
167-
as i16;
165+
revents = unsafe {
166+
sndio_sys::sio_revents(inner_state.hdl.as_ref().unwrap().0, pollfds.as_mut_ptr())
167+
} as i16;
168168
if revents & libc::POLLHUP != 0 {
169169
inner_state.error(backend_specific_error("device disappeared"));
170170
break;
@@ -222,7 +222,7 @@ pub(super) fn runner(inner_state_arc: Arc<Mutex<InnerState>>) {
222222
// unwrap OK because .open was called
223223
let bytes_written = unsafe {
224224
sndio_sys::sio_write(
225-
inner_state.hdl.unwrap(),
225+
inner_state.hdl.as_ref().unwrap().0,
226226
(output_data.data as *const u8).add(output_offset_bytes_into_buf as usize)
227227
as *const _,
228228
data_byte_size as u64 - output_offset_bytes_into_buf,
@@ -271,7 +271,7 @@ pub(super) fn runner(inner_state_arc: Arc<Mutex<InnerState>>) {
271271
// unwrap OK because .open was called
272272
let bytes_read = unsafe {
273273
sndio_sys::sio_read(
274-
inner_state.hdl.unwrap(),
274+
inner_state.hdl.as_ref().unwrap().0,
275275
(input_data.data as *const u8).add(input_offset_bytes_into_buf as usize)
276276
as *mut _,
277277
data_byte_size as u64 - input_offset_bytes_into_buf,

0 commit comments

Comments
 (0)