1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 1 | use std::future::Future; |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 2 | |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 3 | use futures_util::{StreamExt, stream::FuturesUnordered}; |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 4 | use matrix_sdk::SendOutsideWasm; |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 5 | pub(super) use matrix_sdk::executor::{AbortHandle, JoinError, JoinHandle, spawn}; |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 6 | |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 7 | #[cfg(not(target_family = "wasm"))] |
a319bae745d8 | atagen | 2026-09-26 09:59 UTC | 8 | pub(crate) type EngineBoxFuture<'a, T> = futures_util::future::BoxFuture<'a, T>; |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 9 | #[cfg(target_family = "wasm")] |
a319bae745d8 | atagen | 2026-09-26 09:59 UTC | 10 | pub(crate) type EngineBoxFuture<'a, T> = futures_util::future::LocalBoxFuture<'a, T>; |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 11 | |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 12 | #[cfg(not(target_family = "wasm"))] |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 13 | pub(super) fn is_panic(error: &JoinError) -> bool { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 14 | error.is_panic() |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 15 | } |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 16 | |
7b376d620a3d | atagen | 2026-09-26 12:53 UTC | 17 | /// the sdk's wasm join error has no payload, and a real panic traps before it gets here |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 18 | #[cfg(target_family = "wasm")] |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 19 | pub(super) fn is_panic(error: &JoinError) -> bool { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 20 | !error.is_cancelled() |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 21 | } |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 22 | |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 23 | #[cfg(not(target_family = "wasm"))] |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 24 | pub(super) fn resume_unwind(error: JoinError) -> ! { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 25 | std::panic::resume_unwind(error.into_panic()) |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 26 | } |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 27 | |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 28 | #[cfg(target_family = "wasm")] |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 29 | pub(super) fn resume_unwind(error: JoinError) -> ! { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 30 | panic!("{error}") |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 31 | } |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 32 | |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 33 | /// a `JoinSet` that runs on wasm too, and like it aborts whatever's left when dropped |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 34 | pub(super) struct TaskSet<T: 'static> { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 35 | handles: FuturesUnordered<JoinHandle<T>>, |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 36 | } |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 37 | |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 38 | impl<T: 'static> TaskSet<T> { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 39 | pub(super) fn new() -> Self { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 40 | Self { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 41 | handles: FuturesUnordered::new(), |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 42 | } |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 43 | } |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 44 | |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 45 | pub(super) fn spawn( |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 46 | &mut self, |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 47 | task: impl Future<Output = T> + SendOutsideWasm + 'static, |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 48 | ) -> AbortHandle |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 49 | where |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 50 | T: SendOutsideWasm, |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 51 | { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 52 | let handle = spawn(task); |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 53 | let abort = handle.abort_handle(); |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 54 | self.handles.push(handle); |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 55 | abort |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 56 | } |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 57 | |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 58 | pub(super) fn is_empty(&self) -> bool { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 59 | self.handles.is_empty() |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 60 | } |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 61 | |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 62 | pub(super) async fn join_next(&mut self) -> Option<Result<T, JoinError>> { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 63 | self.handles.next().await |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 64 | } |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 65 | |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 66 | fn abort_all(&self) { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 67 | for handle in &self.handles { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 68 | handle.abort(); |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 69 | } |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 70 | } |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 71 | |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 72 | pub(super) async fn shutdown(&mut self) { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 73 | self.abort_all(); |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 74 | while self.handles.next().await.is_some() {} |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 75 | } |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 76 | } |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 77 | |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 78 | impl<T: 'static> Drop for TaskSet<T> { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 79 | fn drop(&mut self) { |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 80 | self.abort_all(); |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 81 | } |
1fe480c16a3c | atagen | 2026-09-26 08:44 UTC | 82 | } |
a5865326c81b | atagen | 2026-10-26 06:44 UTC | 83 | |
a5865326c81b | atagen | 2026-10-26 06:44 UTC | 84 | /// a store cipher's pbkdf2 holds its thread for over a second in a debug build, so natively it |
a5865326c81b | atagen | 2026-10-26 06:44 UTC | 85 | /// runs beside the runtime and two stores can derive at once |
a5865326c81b | atagen | 2026-10-26 06:44 UTC | 86 | #[cfg(not(target_family = "wasm"))] |
a5865326c81b | atagen | 2026-10-26 06:44 UTC | 87 | pub(crate) async fn derive<T: Send + 'static>(work: impl FnOnce() -> T + Send + 'static) -> T { |
a5865326c81b | atagen | 2026-10-26 06:44 UTC | 88 | tokio::task::spawn_blocking(work) |
a5865326c81b | atagen | 2026-10-26 06:44 UTC | 89 | .await |
a5865326c81b | atagen | 2026-10-26 06:44 UTC | 90 | .unwrap_or_else(|error| std::panic::resume_unwind(error.into_panic())) |
a5865326c81b | atagen | 2026-10-26 06:44 UTC | 91 | } |
a5865326c81b | atagen | 2026-10-26 06:44 UTC | 92 | |
a5865326c81b | atagen | 2026-10-26 06:44 UTC | 93 | #[cfg(target_family = "wasm")] |
a5865326c81b | atagen | 2026-10-26 06:44 UTC | 94 | pub(crate) async fn derive<T>(work: impl FnOnce() -> T) -> T { |
a5865326c81b | atagen | 2026-10-26 06:44 UTC | 95 | work() |
a5865326c81b | atagen | 2026-10-26 06:44 UTC | 96 | } |