blob: aa1a00bb07e96cb6ba500a563d3f92899972dbcd (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
use std::sync::{Arc, Mutex};
use super::response::SwiftMullvadApiResponse;
unsafe extern "C" {
/// Maps to `mullvadApiCompletionFinish` on Swift side to facilitate callback based completion flow when doing
/// network calls through Mullvad API on Rust side.
///
/// # Safety
///
/// `response` must be pointing to a valid instance of `SwiftMullvadApiResponse`.
///
/// `completion_cookie` must be pointing to a valid instance of `CompletionCookie`. `CompletionCookie` is safe
/// because the pointer in `MullvadApiCompletion` is valid for the lifetime of the process where this type is
/// intended to be used.
pub fn mullvad_api_completion_finish(
response: SwiftMullvadApiResponse,
completion_cookie: CompletionCookie,
);
}
#[repr(C)]
pub struct CompletionCookie {
inner: *mut std::ffi::c_void,
}
/// SAFETY: Access to `CompletionCookie` should always be done through a `SwiftCompletionHandler`
/// It is safe to be used and sent from any threads.
unsafe impl Send for CompletionCookie {}
impl CompletionCookie {
/// `inner` must be pointing to a valid instance of Swift object `MullvadApiCompletion`.
pub unsafe fn new(inner: *mut std::ffi::c_void) -> Self {
Self { inner }
}
}
#[derive(Clone)]
pub struct SwiftCompletionHandler {
inner: Arc<Mutex<Option<CompletionCookie>>>,
}
impl SwiftCompletionHandler {
pub fn new(cookie: CompletionCookie) -> Self {
Self {
inner: Arc::new(Mutex::new(Some(cookie))),
}
}
// This function makes sure that completion is done only once.
pub fn finish(&self, response: SwiftMullvadApiResponse) {
let Ok(mut maybe_cookie) = self.inner.lock() else {
log::error!("Response handler panicked");
return;
};
let Some(cookie) = maybe_cookie.take() else {
return;
};
// SAFETY: See safety notes for `mullvad_api_completion_finish`
unsafe { mullvad_api_completion_finish(response, cookie) };
}
}
|