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)
| 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 { |
no test coverage detected