output_handle.rs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. use alloc::sync::Arc;
  2. use core::task::Waker;
  3. use eonix_sync::Spin;
  4. enum OutputState<Output>
  5. where
  6. Output: Send,
  7. {
  8. Waiting(Option<Waker>),
  9. Finished(Option<Output>),
  10. TakenOut,
  11. }
  12. pub struct OutputHandle<Output>
  13. where
  14. Output: Send,
  15. {
  16. inner: OutputState<Output>,
  17. }
  18. impl<Output> OutputHandle<Output>
  19. where
  20. Output: Send,
  21. {
  22. pub fn new() -> Arc<Spin<Self>> {
  23. Arc::new(Spin::new(Self {
  24. inner: OutputState::Waiting(None),
  25. }))
  26. }
  27. pub fn try_resolve(&mut self) -> Option<Output> {
  28. let output = match &mut self.inner {
  29. OutputState::Waiting(_) => return None,
  30. OutputState::Finished(output) => output.take(),
  31. OutputState::TakenOut => panic!("Output already taken out"),
  32. };
  33. self.inner = OutputState::TakenOut;
  34. if let Some(output) = output {
  35. Some(output)
  36. } else {
  37. unreachable!("Output should be present")
  38. }
  39. }
  40. pub fn register_waiter(&mut self, waker: Waker) {
  41. if let OutputState::Waiting(inner_waker) = &mut self.inner {
  42. inner_waker.replace(waker);
  43. } else {
  44. panic!("Output is not waiting");
  45. }
  46. }
  47. pub fn commit_output(&mut self, output: Output) {
  48. if let OutputState::Waiting(inner_waker) = &mut self.inner {
  49. if let Some(waker) = inner_waker.take() {
  50. waker.wake();
  51. }
  52. self.inner = OutputState::Finished(Some(output));
  53. } else {
  54. panic!("Output is not waiting");
  55. }
  56. }
  57. }