-
Notifications
You must be signed in to change notification settings - Fork 47
[RFC] Uniform service spawning with external 'resources' #740
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
Open
williampMSFT
wants to merge
1
commit into
OpenDevicePartnership:v0.2.0
Choose a base branch
from
williampMSFT:user/williamp/es-uniform-spawn-with-innersvc
base: v0.2.0
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| //! This module contains helper traits and functions for services that run on the EC. | ||
|
|
||
| /// A trait for a service that can be run on the EC. | ||
| /// Implementations of Service should have an init() function to construct the service that | ||
| /// returns a Runner, which the user is expected to spawn a task for. | ||
| pub trait Service<'hw>: Sized { | ||
| /// A type that can be used to run the service. This is returned by the init() function and the user is | ||
| /// expected to call its run() method in an embassy task (or similar parallel execution context on other | ||
| /// async runtimes). | ||
| type Runner: ServiceRunner<'hw>; | ||
|
|
||
| /// Any memory resources that your service needs. This is typically an opaque types that is only used by the service | ||
| /// and is not interacted with by users of the service. Must be default-constructible for spawn_service!() to work. | ||
| type Resources: ServiceResources; | ||
|
|
||
| /// The error type that your `init` function can return on failure. | ||
| type ErrorType; | ||
|
|
||
| /// Any initialization parameters that your service needs to run. | ||
| type InitParams; | ||
|
|
||
| /// Initializes an instance of the service using the provided storage and returns a control handle for the service and | ||
| /// a runner that can be used to run the service. | ||
| fn new( | ||
| storage: &'hw mut Self::Resources, | ||
| params: Self::InitParams, | ||
| ) -> impl core::future::Future<Output = Result<(Self, Self::Runner), Self::ErrorType>>; | ||
| } | ||
|
|
||
| /// Represents the memory resources that a service needs to run. This is typically an opaque type that is only used by the service. | ||
| /// Must be default-constructible; the service is expected to populate its contents in its init() function. | ||
| pub trait ServiceResources { | ||
| /// Creates a new instance of the service's resources. | ||
| fn new() -> Self; | ||
| } | ||
|
|
||
| /// A trait for a run handle used to execute a service's event loop. This is returned by Service::init() | ||
| /// and the user is expected to call its run() method in an embassy task (or similar parallel execution context | ||
| /// on other async runtimes). | ||
| pub trait ServiceRunner<'hw> { | ||
| /// Run the service event loop. This future never completes. | ||
| fn run(self) -> impl core::future::Future<Output = crate::Never> + 'hw; | ||
| } | ||
|
|
||
| /// Initializes a service, creates an embassy task to run it, and spawns that task. | ||
| /// | ||
| /// This macro handles the boilerplate of: | ||
| /// 1. Creating a `static` [`OnceLock`](embassy_sync::once_lock::OnceLock) to hold the service | ||
| /// 2. Calling the service's `init()` method | ||
| /// 3. Defining an embassy_executor::task to run the service | ||
| /// 4. Spawning the task on the provided executor | ||
| /// | ||
| /// Returns a Result<reference-to-service, Error> where Error is the error type of $service_ty::init(). | ||
| /// | ||
| /// Arguments | ||
| /// | ||
| /// - spawner: An embassy_executor::Spawner. | ||
| /// - service_ty: The service type that implements Service that you want to create and run. | ||
| /// - init_arg: The init argument type to pass to `Service::init()` | ||
| /// | ||
| /// Example: | ||
| /// | ||
| /// ```ignore | ||
| /// let time_service = embedded_services::spawn_service!( | ||
| /// spawner, | ||
| /// time_alarm_service::Service<'static>, | ||
| /// time_alarm_service::ServiceInitParams { dt_clock, tz, ac_expiration, ac_policy, dc_expiration, dc_policy } | ||
| /// ).expect("failed to initialize time_alarm service"); | ||
| /// ``` | ||
| #[macro_export] | ||
| macro_rules! spawn_service { | ||
| ($spawner:expr, $service_ty:ty, $init_arg:expr) => {{ | ||
| use $crate::service::{Service, ServiceResources, ServiceRunner}; | ||
| static SERVICE_RESOURCES: StaticCell<(<$service_ty as Service>::Resources)> = StaticCell::new(); | ||
| let service_resources = | ||
| SERVICE_RESOURCES.init(<<$service_ty as Service>::Resources as ServiceResources>::new()); | ||
|
|
||
| #[embassy_executor::task] | ||
| async fn service_task_fn(runner: <$service_ty as $crate::service::Service<'static>>::Runner) { | ||
| runner.run().await; | ||
| } | ||
|
|
||
| <$service_ty>::new(service_resources, $init_arg) | ||
| .await | ||
| .map(|(control_handle, runner)| { | ||
| $spawner.must_spawn(service_task_fn(runner)); | ||
| control_handle | ||
| }) | ||
| }}; | ||
| } | ||
|
|
||
| pub use spawn_service; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,8 +22,5 @@ | |
| #[cfg(not(test))] | ||
| mod espi_service; | ||
|
|
||
| #[cfg(not(test))] | ||
| pub mod task; | ||
|
|
||
| #[cfg(not(test))] | ||
| pub use espi_service::*; | ||
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.