Skip to content

Commit b25d6d4

Browse files
authored
Make safer. (#209)
* Make shutdown unsafe. * Don't return client,processor,notification if there was a panic. * Bump major version.
1 parent 02a5936 commit b25d6d4

File tree

5 files changed

+21
-16
lines changed

5 files changed

+21
-16
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ license = "MIT"
88
name = "jack"
99
readme = "README.md"
1010
repository = "https://github.com/RustAudio/rust-jack"
11-
version = "0.12.2"
11+
version = "0.13.0"
1212

1313
[dependencies]
1414
bitflags = "2"

examples/playback_capture.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,8 @@ impl jack::NotificationHandler for Notifications {
5151
println!("JACK: thread init");
5252
}
5353

54-
fn shutdown(&mut self, status: jack::ClientStatus, reason: &str) {
55-
println!("JACK: shutdown with status {status:?} because \"{reason}\"",);
56-
}
54+
/// Not much we can do here, see https://man7.org/linux/man-pages/man7/signal-safety.7.html.
55+
unsafe fn shutdown(&mut self, _: jack::ClientStatus, _: &str) {}
5756

5857
fn freewheel(&mut self, _: &jack::Client, is_enabled: bool) {
5958
println!(

src/client/async_client.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ impl<N, P> AsyncClient<N, P> {
111111
if self.callback.is_none() {
112112
return Err(Error::ClientIsNoLongerAlive);
113113
}
114-
let cb = self.callback.take().unwrap();
114+
let cb = self.callback.take().ok_or(Error::ClientIsNoLongerAlive)?;
115115
let client = cb.client.raw();
116116

117117
// deactivate
@@ -124,7 +124,13 @@ impl<N, P> AsyncClient<N, P> {
124124
sleep_on_test();
125125
clear_callbacks(client)?;
126126
// done, take ownership of callback
127-
Ok(cb)
127+
if cb.is_valid.load(std::sync::atomic::Ordering::Relaxed) {
128+
Ok(cb)
129+
} else {
130+
std::mem::forget(cb.notification);
131+
std::mem::forget(cb.process);
132+
Err(Error::ClientIsNoLongerAlive)
133+
}
128134
}
129135
}
130136

src/client/callbacks.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ pub trait NotificationHandler: Send {
1616
/// It does not need to be suitable for real-time execution.
1717
fn thread_init(&self, _: &Client) {}
1818

19-
/// Called when the JACK server shuts down the client thread. The function
20-
/// must be written as if
21-
/// it were an asynchronous POSIX signal handler --- use only async-safe
22-
/// functions, and remember
23-
/// that it is executed from another thread. A typical funcion might set a
24-
/// flag or write to a
25-
/// pipe so that the rest of the application knows that the JACK client
26-
/// thread has shut down.
27-
fn shutdown(&mut self, _status: ClientStatus, _reason: &str) {}
19+
/// Called when the JACK server shuts down the client thread. The function must be written as if
20+
/// it were an asynchronous POSIX signal handler --- use only async-safe functions, and remember
21+
/// that it is executed from another thread. A typical funcion might set a flag or write to a
22+
/// pipe so that the rest of the application knows that the JACK client thread has shut down.
23+
///
24+
/// # Safety
25+
/// See https://man7.org/linux/man-pages/man7/signal-safety.7.html for details about
26+
/// what is legal in an async-signal-safe callback.
27+
unsafe fn shutdown(&mut self, _status: ClientStatus, _reason: &str) {}
2828

2929
/// Called whenever "freewheel" mode is entered or leaving.
3030
fn freewheel(&mut self, _: &Client, _is_freewheel_enabled: bool) {}

src/client/test_callback.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ fn client_cback_has_proper_default_callbacks() {
8686
let ps = unsafe { ProcessScope::from_raw(0, ptr::null_mut()) };
8787
// check each callbacks
8888
().thread_init(&wc);
89-
().shutdown(client_status::ClientStatus::empty(), "mock");
89+
unsafe { ().shutdown(client_status::ClientStatus::empty(), "mock") };
9090
assert_eq!(().process(&wc, &ps), Control::Continue);
9191
().freewheel(&wc, true);
9292
().freewheel(&wc, false);

0 commit comments

Comments
 (0)