Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/utils/async_job_queue.rs
5394 views
1
// Copyright 2018 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
use std::mem;
6
use std::sync::Arc;
7
8
use anyhow::Context;
9
use base::Event;
10
use base::EventType;
11
use sync::Mutex;
12
13
use super::Error;
14
use super::EventHandler;
15
use super::EventLoop;
16
use super::Result;
17
18
/// Async Job Queue can schedule async jobs.
19
pub struct AsyncJobQueue {
20
jobs: Mutex<Vec<Box<dyn FnMut() + Send>>>,
21
evt: Event,
22
}
23
24
impl AsyncJobQueue {
25
/// Init job queue on event loop.
26
pub fn init(event_loop: &EventLoop) -> Result<Arc<AsyncJobQueue>> {
27
let evt = Event::new().map_err(Error::CreateEvent)?;
28
let queue = Arc::new(AsyncJobQueue {
29
jobs: Mutex::new(Vec::new()),
30
evt,
31
});
32
let handler: Arc<dyn EventHandler> = queue.clone();
33
event_loop.add_event(&queue.evt, EventType::Read, Arc::downgrade(&handler))?;
34
Ok(queue)
35
}
36
37
/// Queue a new job. It will be invoked on event loop.
38
pub fn queue_job<T: Fn() + 'static + Send>(&self, cb: T) -> Result<()> {
39
self.jobs.lock().push(Box::new(cb));
40
self.evt.signal().map_err(Error::WriteEvent)
41
}
42
}
43
44
impl EventHandler for AsyncJobQueue {
45
fn on_event(&self) -> anyhow::Result<()> {
46
// We want to read out the event.
47
self.evt.wait().context("read event failed")?;
48
49
let jobs = mem::take(&mut *self.jobs.lock());
50
for mut cb in jobs {
51
cb();
52
}
53
Ok(())
54
}
55
}
56
57