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
63
64
65
66
67
68
69
70
71
72
73
74
75
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
// ------------------------------------------------------------
use std::{fmt::Debug, future::Future, pin::Pin};
// Executor is used by rs to post jobs to execute in the background
// Sync is needed due to we use the executor across await boundary.
pub trait Executor: Clone + Sync + Send + 'static {
// Required functions
/// spawns the task to run in background.
/// This is primarily used by mssf Bridge to execute user app async callbacks/notifications.
fn spawn<F>(&self, future: F)
where
F: Future + Send + 'static,
F::Output: Send;
/// Runs the provided function on an executor dedicated to blocking
/// operations.
fn spawn_blocking<F, R>(&self, func: F)
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static;
}
/// Runtime independent sleep trait.
pub trait Timer: Send + Sync + 'static {
/// Returns a future that is ready after duration.
fn sleep(&self, duration: std::time::Duration) -> Pin<Box<dyn EventFuture>>;
}
/// Runtime independent event future.
pub trait EventFuture: Send + Future<Output = ()> {}
impl<T> EventFuture for T where T: Future<Output = ()> + Send {}
pub trait CancelToken: Send + Sync + 'static {
/// Get a future to wait for cancellation.
fn wait(&self) -> Pin<Box<dyn EventFuture>>;
/// Is the token cancelled
fn is_cancelled(&self) -> bool;
/// Cancel the token.
fn cancel(&self);
/// Register a callback to be invoked when this token is cancelled.
/// If this token is already cancelled, the callback is invoked immediately.
///
/// # Panics (debug builds only)
/// Panics if a callback has already been registered.
fn on_cancel(&self, callback: Box<dyn FnOnce() + Send + Sync>);
/// Clone the cancel token.
/// Because the dyn requirement, CancelToken cannot be cloned directly.
fn clone_box(&self) -> Box<dyn CancelToken>;
}
pub type BoxedCancelToken = Box<dyn CancelToken>;
impl Clone for BoxedCancelToken {
fn clone(&self) -> Self {
self.clone_box()
}
}
impl Debug for dyn CancelToken {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CancelToken")
.field("cancelled", &self.is_cancelled())
.finish()
}
}