builder.rs 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. use super::{Executor, OutputHandle, RealExecutor, Stack};
  2. use crate::{
  3. context::ExecutionContext,
  4. run::{Contexted, Run},
  5. };
  6. use alloc::{boxed::Box, sync::Arc};
  7. use core::{pin::Pin, sync::atomic::AtomicBool};
  8. use eonix_sync::Spin;
  9. pub struct ExecutorBuilder<S, R> {
  10. stack: Option<S>,
  11. runnable: Option<R>,
  12. }
  13. impl<S, R> ExecutorBuilder<S, R>
  14. where
  15. S: Stack,
  16. R: Run + Contexted + Send + 'static,
  17. R::Output: Send,
  18. {
  19. pub fn new() -> Self {
  20. Self {
  21. stack: None,
  22. runnable: None,
  23. }
  24. }
  25. pub fn stack(mut self, stack: S) -> Self {
  26. self.stack.replace(stack);
  27. self
  28. }
  29. pub fn runnable(mut self, runnable: R) -> Self {
  30. self.runnable.replace(runnable);
  31. self
  32. }
  33. pub fn build(
  34. mut self,
  35. ) -> (
  36. Pin<Box<impl Executor>>,
  37. ExecutionContext,
  38. Arc<Spin<OutputHandle<R::Output>>>,
  39. ) {
  40. let stack = self.stack.take().expect("Stack is required");
  41. let runnable = self.runnable.take().expect("Runnable is required");
  42. let mut execution_context = ExecutionContext::new();
  43. let output_handle = OutputHandle::new();
  44. execution_context.set_sp(stack.get_bottom() as *const _ as _);
  45. let executor = Box::pin(RealExecutor {
  46. _stack: stack,
  47. runnable,
  48. output_handle: Arc::downgrade(&output_handle),
  49. finished: AtomicBool::new(false),
  50. });
  51. execution_context.call1(
  52. RealExecutor::<S, R>::execute,
  53. executor.as_ref().get_ref() as *const _ as usize,
  54. );
  55. (executor, execution_context, output_handle)
  56. }
  57. }