embassy_executor/arch/
std.rs1#[cfg(feature = "executor-interrupt")]
2compile_error!("`executor-interrupt` is not supported with `arch-std`.");
3
4#[cfg(feature = "executor-thread")]
5pub use thread::*;
6#[cfg(feature = "executor-thread")]
7mod thread {
8 use std::marker::PhantomData;
9 use std::sync::{Condvar, Mutex};
10
11 pub use embassy_executor_macros::main_std as main;
12
13 use crate::{raw, Spawner};
14
15 #[export_name = "__pender"]
16 fn __pender(context: *mut ()) {
17 let signaler: &'static Signaler = unsafe { std::mem::transmute(context) };
18 signaler.signal()
19 }
20
21 pub struct Executor {
23 inner: raw::Executor,
24 not_send: PhantomData<*mut ()>,
25 signaler: &'static Signaler,
26 }
27
28 impl Executor {
29 pub fn new() -> Self {
31 let signaler = Box::leak(Box::new(Signaler::new()));
32 Self {
33 inner: raw::Executor::new(signaler as *mut Signaler as *mut ()),
34 not_send: PhantomData,
35 signaler,
36 }
37 }
38
39 pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
58 init(self.inner.spawner());
59
60 loop {
61 unsafe { self.inner.poll() };
62 self.signaler.wait()
63 }
64 }
65 }
66
67 struct Signaler {
68 mutex: Mutex<bool>,
69 condvar: Condvar,
70 }
71
72 impl Signaler {
73 fn new() -> Self {
74 Self {
75 mutex: Mutex::new(false),
76 condvar: Condvar::new(),
77 }
78 }
79
80 fn wait(&self) {
81 let mut signaled = self.mutex.lock().unwrap();
82 while !*signaled {
83 signaled = self.condvar.wait(signaled).unwrap();
84 }
85 *signaled = false;
86 }
87
88 fn signal(&self) {
89 let mut signaled = self.mutex.lock().unwrap();
90 *signaled = true;
91 self.condvar.notify_one();
92 }
93 }
94}