• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium OS Authors. All rights reserved.
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 super::{Error, Result};
6 use super::{EventHandler, EventLoop};
7 use base::{error, Event, WatchingEvents};
8 use std::mem;
9 use std::sync::Arc;
10 use sync::Mutex;
11 
12 /// Async Job Queue can schedule async jobs.
13 pub struct AsyncJobQueue {
14     jobs: Mutex<Vec<Box<dyn FnMut() + Send>>>,
15     evt: Event,
16 }
17 
18 impl AsyncJobQueue {
19     /// Init job queue on event loop.
init(event_loop: &EventLoop) -> Result<Arc<AsyncJobQueue>>20     pub fn init(event_loop: &EventLoop) -> Result<Arc<AsyncJobQueue>> {
21         let evt = Event::new().map_err(Error::CreateEvent)?;
22         let queue = Arc::new(AsyncJobQueue {
23             jobs: Mutex::new(Vec::new()),
24             evt,
25         });
26         let handler: Arc<dyn EventHandler> = queue.clone();
27         event_loop.add_event(
28             &queue.evt,
29             WatchingEvents::empty().set_read(),
30             Arc::downgrade(&handler),
31         )?;
32         Ok(queue)
33     }
34 
35     /// Queue a new job. It will be invoked on event loop.
queue_job<T: Fn() + 'static + Send>(&self, cb: T) -> Result<()>36     pub fn queue_job<T: Fn() + 'static + Send>(&self, cb: T) -> Result<()> {
37         self.jobs.lock().push(Box::new(cb));
38         self.evt.write(1).map_err(Error::WriteEvent)
39     }
40 }
41 
42 impl EventHandler for AsyncJobQueue {
on_event(&self) -> std::result::Result<(), ()>43     fn on_event(&self) -> std::result::Result<(), ()> {
44         // We want to read out the event, but the value is not important.
45         match self.evt.read() {
46             Ok(_) => {}
47             Err(e) => {
48                 error!("read event failed {}", e);
49                 return Err(());
50             }
51         }
52 
53         let jobs = mem::replace(&mut *self.jobs.lock(), Vec::new());
54         for mut cb in jobs {
55             cb();
56         }
57         Ok(())
58     }
59 }
60