Skip to content

Commit 53ee03b

Browse files
committed
refactor: replace mpsc channel with Mutex+Condvar in content sharing picker
Consistent with screenshot_manager refactor - use simpler sync primitives
1 parent 4b111bd commit 53ee03b

1 file changed

Lines changed: 35 additions & 12 deletions

File tree

src/content_sharing_picker.rs

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,25 @@
77
88
use crate::shareable_content::{SCDisplay, SCRunningApplication, SCWindow};
99
use std::ffi::c_void;
10+
use std::sync::{Arc, Mutex, Condvar};
11+
12+
/// Shared state for synchronous picker
13+
struct SyncPickerState {
14+
result: Option<SCContentSharingPickerResult>,
15+
}
16+
17+
/// Holder for state + condvar
18+
struct SyncPicker {
19+
state: Mutex<SyncPickerState>,
20+
condvar: Condvar,
21+
}
1022

1123
extern "C" fn picker_callback(
1224
result_code: i32,
1325
stream_ptr: *const c_void,
1426
user_data: *mut c_void,
1527
) {
16-
let tx = unsafe {
17-
Box::from_raw(
18-
user_data.cast::<std::sync::mpsc::Sender<SCContentSharingPickerResult>>(),
19-
)
20-
};
28+
let picker = unsafe { Arc::from_raw(user_data.cast::<SyncPicker>()) };
2129

2230
let result = match result_code {
2331
0 => SCContentSharingPickerResult::Cancelled,
@@ -30,7 +38,14 @@ extern "C" fn picker_callback(
3038
_ => SCContentSharingPickerResult::Cancelled,
3139
};
3240

33-
let _ = tx.send(result);
41+
{
42+
let mut state = picker.state.lock().unwrap();
43+
state.result = Some(result);
44+
}
45+
picker.condvar.notify_one();
46+
47+
// Release our reference - the caller still holds one
48+
drop(picker);
3449
}
3550

3651
/// Picker style determines what content types can be selected
@@ -136,18 +151,26 @@ impl SCContentSharingPicker {
136151
pub fn show(
137152
config: &SCContentSharingPickerConfiguration,
138153
) -> SCContentSharingPickerResult {
139-
let (tx, rx) = std::sync::mpsc::channel();
154+
let picker = Arc::new(SyncPicker {
155+
state: Mutex::new(SyncPickerState { result: None }),
156+
condvar: Condvar::new(),
157+
});
140158

141-
let user_data = Box::into_raw(Box::new(tx)).cast::<c_void>();
159+
let user_data = Arc::into_raw(picker.clone()).cast_mut().cast::<c_void>();
142160

143161
unsafe {
144162
crate::ffi::sc_content_sharing_picker_show(config.as_ptr(), picker_callback, user_data);
145163
}
146164

147-
rx.recv()
148-
.unwrap_or(SCContentSharingPickerResult::Error(
149-
"Failed to receive result".to_string(),
150-
))
165+
// Wait for callback
166+
let mut state = picker.state.lock().unwrap();
167+
while state.result.is_none() {
168+
state = picker.condvar.wait(state).unwrap();
169+
}
170+
171+
state.result.take().unwrap_or(SCContentSharingPickerResult::Error(
172+
"Failed to receive result".to_string(),
173+
))
151174
}
152175
}
153176

0 commit comments

Comments
 (0)