drumbeat/sync/
runtime.rs

1use super::threadpool::{Task, ThreadPool, ThreadPoolBuilder};
2
3use std::sync::Arc;
4
5// HashMap<ThreadId, AtomicBool> -> A map of threads to errors. The future will poll this map to see if the worker errored out
6pub struct Runtime;
7
8impl Runtime {
9  fn get() -> Arc<ThreadPool> {
10    lazy_static! {
11      static ref POOL: Arc<ThreadPool> = Arc::new(ThreadPoolBuilder::named("runtime".to_owned()).build());
12    }
13    POOL.clone()
14  }
15
16  /// Submits a given task to be run asynchronously on the drumbeat runtime
17  /// which is currently implemented as a thread pool, see
18  /// [this method](ThreadPool::submit) for details
19  pub fn submit<F>(job: F)
20  where
21    F: Fn() + Send + Sync + 'static,
22  {
23    Runtime::submit_raw(Task::new(job));
24  }
25
26  pub fn submit_raw(task: Task) {
27    Runtime::get().submit_raw(task);
28  }
29
30  /// Returns true if runtime has completed all jobs and is standing idle
31  pub fn done() -> bool {
32    Runtime::get().done()
33  }
34}
35
36#[cfg(test)]
37mod test {
38  use super::*;
39  use crate::utils::testing::async_context;
40
41  use std::sync::atomic::{AtomicUsize, Ordering};
42
43  #[test]
44  fn submit_runtime_jobs_test() {
45    async_context(|| {
46      let atomic = Arc::new(AtomicUsize::new(0));
47      for _ in 0..100 {
48        let reference = atomic.clone();
49        Runtime::submit(move || {
50          reference.fetch_add(1, Ordering::Relaxed);
51        });
52      }
53      while !Runtime::done() {}
54      assert_eq!(atomic.load(Ordering::Relaxed), 100);
55    });
56  }
57}