-
Notifications
You must be signed in to change notification settings - Fork 1k
#[test] Attribute Macro for embassy-executor #4201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
823b944
6b0b28e
3839baf
02e5e07
b61bc4a
00fb75f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
pub mod main; | ||
pub mod task; | ||
pub mod test; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
use proc_macro::TokenStream; | ||
use quote::{format_ident, quote}; | ||
use syn::{parse_macro_input, ItemFn}; | ||
|
||
pub fn test(_args: TokenStream, input: TokenStream) -> TokenStream { | ||
let input_fn = parse_macro_input!(input as ItemFn); | ||
let fn_name = &input_fn.sig.ident; | ||
|
||
let task_name = format_ident!("__{}_task", fn_name); | ||
|
||
let gen = quote! { | ||
#[::embassy_executor::task()] | ||
#[allow(clippy::future_not_send)] | ||
async fn #task_name() { | ||
#input_fn | ||
} | ||
|
||
|
||
#[test] | ||
fn #fn_name() { | ||
let mut executor = ::embassy_executor::Executor::new(); | ||
let executor = unsafe { ::core::mem::transmute::<_, &'static mut ::embassy_executor::Executor>(&mut executor) }; | ||
executor.run(|spawner| { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this will run forever, the test won't complete even if the task returns. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wow, you're so fast! I didn't even have time to make the formatter happy. You're right, that's actually one of my concerns. Currently, From what I can see, That said, I'll need to implement all of that for all arch by myself. What do you think? |
||
spawner.spawn(#task_name()).unwrap(); | ||
}); | ||
} | ||
}; | ||
|
||
gen.into() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is unsound, the executor really needs
&'static mut self
. Even if all tasks stop running, they keep pointers to the executors and anything can keep a pointer to a task through a waker, so you can't ensure the executor won't be use-after-free'd.(it's currently sound due to my other comment (run never returrns) but it won't be when that's fixed)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A little unsound indeed.
What would be the best approach then? Should I make it static inside the function body using a
StaticCell
?That would require the end user to either import
static_cell
themselves, or forstatic_cell
to be re-exported by Embassy.