|
- use std::sync::{Arc, Condvar, Mutex};
- use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
-
- #[cfg(feature = "bench")]
- mod bench;
- mod index;
- mod merge;
- mod new;
- mod search;
- mod serve;
-
- #[cfg(feature = "bench")]
- pub use self::bench::run_bench_cli;
- pub use self::index::run_index_cli;
- pub use self::merge::run_merge_cli;
- pub use self::new::run_new_cli;
- pub use self::search::run_search_cli;
- pub use self::serve::run_serve_cli;
-
- // stolen from [extreme](https://github.com/spacejam/extreme)
-
- #[derive(Default)]
- struct Park(Mutex<bool>, Condvar);
-
- fn unpark(park: &Park) {
- *park.0.lock().unwrap() = true;
- park.1.notify_one();
- }
-
- static VTABLE: RawWakerVTable = RawWakerVTable::new(
- |clone_me| unsafe {
- let arc = Arc::from_raw(clone_me as *const Park);
- std::mem::forget(arc.clone());
- RawWaker::new(Arc::into_raw(arc) as *const (), &VTABLE)
- },
- |wake_me| unsafe { unpark(&Arc::from_raw(wake_me as *const Park)) },
- |wake_by_ref_me| unsafe { unpark(&*(wake_by_ref_me as *const Park)) },
- |drop_me| unsafe { drop(Arc::from_raw(drop_me as *const Park)) },
- );
-
- /// Run a `Future`.
- pub fn run<F: std::future::Future>(mut f: F) -> F::Output {
- let mut f = unsafe { std::pin::Pin::new_unchecked(&mut f) };
- let park = Arc::new(Park::default());
- let sender = Arc::into_raw(park.clone());
- let raw_waker = RawWaker::new(sender as *const _, &VTABLE);
- let waker = unsafe { Waker::from_raw(raw_waker) };
- let mut cx = Context::from_waker(&waker);
-
- loop {
- match f.as_mut().poll(&mut cx) {
- Poll::Pending => {
- let mut runnable = park.0.lock().unwrap();
- while !*runnable {
- runnable = park.1.wait(runnable).unwrap();
- }
- *runnable = false;
- }
- Poll::Ready(val) => return val,
- }
- }
- }
|