sel4_microkit_base/
handler.rs1use core::fmt;
8
9use crate::{
10 Channel, Child, MessageInfo,
11 defer::{DeferredAction, PreparedDeferredAction},
12 ipc::{self, ChannelSet, Event},
13 pd_is_passive,
14};
15
16pub use core::convert::Infallible;
17
18pub trait Handler {
20 type Error: fmt::Display;
22
23 fn notified(&mut self, channels: ChannelSet) -> Result<(), Self::Error> {
27 panic!(
28 "unexpected notification from channels {}",
29 channels.display()
30 )
31 }
32
33 fn protected(
37 &mut self,
38 channel: Channel,
39 msg_info: MessageInfo,
40 ) -> Result<MessageInfo, Self::Error> {
41 panic!(
42 "unexpected protected procedure call from channel {channel:?} with msg_info={msg_info:?}"
43 )
44 }
45
46 fn fault(
50 &mut self,
51 child: Child,
52 msg_info: MessageInfo,
53 ) -> Result<Option<MessageInfo>, Self::Error> {
54 panic!("unexpected fault from protection domain {child:?} with msg_info={msg_info:?}")
55 }
56
57 fn take_deferred_action(&mut self) -> Option<DeferredAction> {
63 None
64 }
65
66 #[doc(hidden)]
67 fn run(&mut self) -> Result<Never, Self::Error> {
68 let mut reply_tag: Option<MessageInfo> = None;
69
70 let mut prepared_deferred_action: Option<PreparedDeferredAction> = if pd_is_passive() {
71 Some(ipc::forfeit_sc())
72 } else {
73 None
74 };
75
76 loop {
77 let event = match (reply_tag.take(), prepared_deferred_action.take()) {
78 (Some(msg_info), None) => ipc::reply_recv(msg_info),
79 (None, Some(action)) => ipc::nb_send_recv(action),
80 (None, None) => ipc::recv(),
81 _ => panic!("handler yielded deferred action after call to 'protected()'"),
82 };
83
84 match event {
85 Event::Notified(channels) => {
86 self.notified(channels)?;
87 }
88 Event::Protected(channel, msg_info) => {
89 reply_tag = Some(self.protected(channel, msg_info)?);
90 }
91 Event::Fault(child, msg_info) => {
92 reply_tag = self.fault(child, msg_info)?;
93 }
94 };
95
96 prepared_deferred_action = self
97 .take_deferred_action()
98 .as_ref()
99 .map(DeferredAction::prepare);
100 }
101 }
102}
103
104#[doc(hidden)]
105pub enum Never {}
106
107impl Handler for Never {
108 type Error = Infallible;
109}
110
111pub struct NullHandler(());
113
114impl NullHandler {
115 #[allow(clippy::new_without_default)]
116 pub fn new() -> Self {
117 Self(())
118 }
119}
120
121impl Handler for NullHandler {
122 type Error = Infallible;
123}