MCPcopy Create free account
hub / github.com/bytecodealliance/wit-bindgen / callback

Method callback

crates/guest-rust/src/rt/async_support.rs:180–283  ·  view source on GitHub ↗

Handles the `event{0,1,2}` event codes and returns a corresponding return code along with a flag whether this future is "done" or not.

(&mut self, event0: u32, event1: u32, event2: u32)

Source from the content-addressed store, hash-verified

178 /// Handles the `event{0,1,2}` event codes and returns a corresponding
179 /// return code along with a flag whether this future is "done" or not.
180 fn callback(&mut self, event0: u32, event1: u32, event2: u32) -> CallbackCode {
181 match event0 {
182 EVENT_NONE => rtdebug!("EVENT_NONE"),
183 EVENT_SUBTASK => rtdebug!("EVENT_SUBTASK({event1:#x}, {event2:#x})"),
184 EVENT_STREAM_READ => rtdebug!("EVENT_STREAM_READ({event1:#x}, {event2:#x})"),
185 EVENT_STREAM_WRITE => rtdebug!("EVENT_STREAM_WRITE({event1:#x}, {event2:#x})"),
186 EVENT_FUTURE_READ => rtdebug!("EVENT_FUTURE_READ({event1:#x}, {event2:#x})"),
187 EVENT_FUTURE_WRITE => rtdebug!("EVENT_FUTURE_WRITE({event1:#x}, {event2:#x})"),
188 EVENT_CANCEL => {
189 rtdebug!("EVENT_CANCEL");
190
191 // Cancellation is mapped to destruction in Rust, so return a
192 // code/bool indicating we're done. The caller will then
193 // appropriately deallocate this `FutureState` which will
194 // transitively run all destructors.
195 return CallbackCode::Exit;
196 }
197 _ => unreachable!(),
198 }
199
200 self.with_p3_task_set(|me| {
201 // Transition our sleep state to ensure that the inter-task stream
202 // isn't used since there's no need to use that here.
203 me.waker
204 .sleep_state
205 .store(SLEEP_STATE_WOKEN, Ordering::Relaxed);
206
207 // With all of our context now configured, deliver the event
208 // notification this callback corresponds to.
209 //
210 // Note that this should happen under the reset of
211 // `waker.sleep_state` above to ensure that if a waker is woken it
212 // won't actually signal our inter-task stream since we're already
213 // in the process of handling the future.
214 if event0 != EVENT_NONE {
215 me.deliver_waitable_event(event1, event2)
216 }
217
218 // If there's still an in-progress read (e.g. `event{1,2}`) wasn't
219 // ourselves getting woken up, then cancel the read since we're
220 // processing the future here anyway.
221 me.cancel_inter_task_stream_read();
222
223 loop {
224 let mut context = Context::from_waker(&me.waker_clone);
225
226 // On each turn of this loop reset the state to "polling"
227 // which clears out any pending wakeup if one was sent. This
228 // in theory helps minimize wakeups from previous iterations
229 // happening in this iteration.
230 me.waker
231 .sleep_state
232 .store(SLEEP_STATE_POLLING, Ordering::Relaxed);
233
234 // Poll our future, seeing if it was able to make progress.
235 let poll = me.tasks.poll_next(&mut context);
236
237 match poll {

Callers 2

callbackFunction · 0.80
block_onFunction · 0.80

Calls 10

with_p3_task_setMethod · 0.80
remaining_workMethod · 0.80
as_rawMethod · 0.80
storeMethod · 0.45
poll_nextMethod · 0.45
loadMethod · 0.45
pollMethod · 0.45

Tested by

no test coverage detected