xref: /aosp_15_r20/external/crosvm/cros_async/src/queue.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2020 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::VecDeque;
6*bb4ee6a4SAndroid Build Coastguard Worker 
7*bb4ee6a4SAndroid Build Coastguard Worker use async_task::Runnable;
8*bb4ee6a4SAndroid Build Coastguard Worker use sync::Mutex;
9*bb4ee6a4SAndroid Build Coastguard Worker 
10*bb4ee6a4SAndroid Build Coastguard Worker /// A queue of `Runnables`. Intended to be used by executors to keep track of futures that have been
11*bb4ee6a4SAndroid Build Coastguard Worker /// scheduled to run.
12*bb4ee6a4SAndroid Build Coastguard Worker pub struct RunnableQueue {
13*bb4ee6a4SAndroid Build Coastguard Worker     runnables: Mutex<VecDeque<Runnable>>,
14*bb4ee6a4SAndroid Build Coastguard Worker }
15*bb4ee6a4SAndroid Build Coastguard Worker 
16*bb4ee6a4SAndroid Build Coastguard Worker impl RunnableQueue {
17*bb4ee6a4SAndroid Build Coastguard Worker     /// Create a new, empty `RunnableQueue`.
new() -> RunnableQueue18*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new() -> RunnableQueue {
19*bb4ee6a4SAndroid Build Coastguard Worker         RunnableQueue {
20*bb4ee6a4SAndroid Build Coastguard Worker             runnables: Mutex::new(VecDeque::new()),
21*bb4ee6a4SAndroid Build Coastguard Worker         }
22*bb4ee6a4SAndroid Build Coastguard Worker     }
23*bb4ee6a4SAndroid Build Coastguard Worker 
24*bb4ee6a4SAndroid Build Coastguard Worker     /// Schedule `runnable` to run in the future by adding it to this `RunnableQueue`.
push_back(&self, runnable: Runnable)25*bb4ee6a4SAndroid Build Coastguard Worker     pub fn push_back(&self, runnable: Runnable) {
26*bb4ee6a4SAndroid Build Coastguard Worker         self.runnables.lock().push_back(runnable);
27*bb4ee6a4SAndroid Build Coastguard Worker     }
28*bb4ee6a4SAndroid Build Coastguard Worker 
29*bb4ee6a4SAndroid Build Coastguard Worker     /// Remove and return the first `Runnable` in this `RunnableQueue` or `None` if it is empty.
pop_front(&self) -> Option<Runnable>30*bb4ee6a4SAndroid Build Coastguard Worker     pub fn pop_front(&self) -> Option<Runnable> {
31*bb4ee6a4SAndroid Build Coastguard Worker         self.runnables.lock().pop_front()
32*bb4ee6a4SAndroid Build Coastguard Worker     }
33*bb4ee6a4SAndroid Build Coastguard Worker 
34*bb4ee6a4SAndroid Build Coastguard Worker     /// Create an iterator over this `RunnableQueue` that repeatedly calls `pop_front()` until it is
35*bb4ee6a4SAndroid Build Coastguard Worker     /// empty.
iter(&self) -> RunnableQueueIter36*bb4ee6a4SAndroid Build Coastguard Worker     pub fn iter(&self) -> RunnableQueueIter {
37*bb4ee6a4SAndroid Build Coastguard Worker         self.into_iter()
38*bb4ee6a4SAndroid Build Coastguard Worker     }
39*bb4ee6a4SAndroid Build Coastguard Worker }
40*bb4ee6a4SAndroid Build Coastguard Worker 
41*bb4ee6a4SAndroid Build Coastguard Worker impl Default for RunnableQueue {
default() -> Self42*bb4ee6a4SAndroid Build Coastguard Worker     fn default() -> Self {
43*bb4ee6a4SAndroid Build Coastguard Worker         Self::new()
44*bb4ee6a4SAndroid Build Coastguard Worker     }
45*bb4ee6a4SAndroid Build Coastguard Worker }
46*bb4ee6a4SAndroid Build Coastguard Worker 
47*bb4ee6a4SAndroid Build Coastguard Worker impl<'q> IntoIterator for &'q RunnableQueue {
48*bb4ee6a4SAndroid Build Coastguard Worker     type Item = Runnable;
49*bb4ee6a4SAndroid Build Coastguard Worker     type IntoIter = RunnableQueueIter<'q>;
50*bb4ee6a4SAndroid Build Coastguard Worker 
into_iter(self) -> Self::IntoIter51*bb4ee6a4SAndroid Build Coastguard Worker     fn into_iter(self) -> Self::IntoIter {
52*bb4ee6a4SAndroid Build Coastguard Worker         RunnableQueueIter { queue: self }
53*bb4ee6a4SAndroid Build Coastguard Worker     }
54*bb4ee6a4SAndroid Build Coastguard Worker }
55*bb4ee6a4SAndroid Build Coastguard Worker 
56*bb4ee6a4SAndroid Build Coastguard Worker /// An iterator over a `RunnableQueue`.
57*bb4ee6a4SAndroid Build Coastguard Worker pub struct RunnableQueueIter<'q> {
58*bb4ee6a4SAndroid Build Coastguard Worker     queue: &'q RunnableQueue,
59*bb4ee6a4SAndroid Build Coastguard Worker }
60*bb4ee6a4SAndroid Build Coastguard Worker 
61*bb4ee6a4SAndroid Build Coastguard Worker impl<'q> Iterator for RunnableQueueIter<'q> {
62*bb4ee6a4SAndroid Build Coastguard Worker     type Item = Runnable;
next(&mut self) -> Option<Self::Item>63*bb4ee6a4SAndroid Build Coastguard Worker     fn next(&mut self) -> Option<Self::Item> {
64*bb4ee6a4SAndroid Build Coastguard Worker         self.queue.pop_front()
65*bb4ee6a4SAndroid Build Coastguard Worker     }
66*bb4ee6a4SAndroid Build Coastguard Worker }
67