You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mod.rs 1.8KB

7 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. use std::sync::{Arc, Condvar, Mutex};
  2. use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
  3. #[cfg(feature = "bench")]
  4. mod bench;
  5. mod index;
  6. mod merge;
  7. mod new;
  8. mod search;
  9. mod serve;
  10. #[cfg(feature = "bench")]
  11. pub use self::bench::run_bench_cli;
  12. pub use self::index::run_index_cli;
  13. pub use self::merge::run_merge_cli;
  14. pub use self::new::run_new_cli;
  15. pub use self::search::run_search_cli;
  16. pub use self::serve::run_serve_cli;
  17. // stolen from [extreme](https://github.com/spacejam/extreme)
  18. #[derive(Default)]
  19. struct Park(Mutex<bool>, Condvar);
  20. fn unpark(park: &Park) {
  21. *park.0.lock().unwrap() = true;
  22. park.1.notify_one();
  23. }
  24. static VTABLE: RawWakerVTable = RawWakerVTable::new(
  25. |clone_me| unsafe {
  26. let arc = Arc::from_raw(clone_me as *const Park);
  27. std::mem::forget(arc.clone());
  28. RawWaker::new(Arc::into_raw(arc) as *const (), &VTABLE)
  29. },
  30. |wake_me| unsafe { unpark(&Arc::from_raw(wake_me as *const Park)) },
  31. |wake_by_ref_me| unsafe { unpark(&*(wake_by_ref_me as *const Park)) },
  32. |drop_me| unsafe { drop(Arc::from_raw(drop_me as *const Park)) },
  33. );
  34. /// Run a `Future`.
  35. pub fn run<F: std::future::Future>(mut f: F) -> F::Output {
  36. let mut f = unsafe { std::pin::Pin::new_unchecked(&mut f) };
  37. let park = Arc::new(Park::default());
  38. let sender = Arc::into_raw(park.clone());
  39. let raw_waker = RawWaker::new(sender as *const _, &VTABLE);
  40. let waker = unsafe { Waker::from_raw(raw_waker) };
  41. let mut cx = Context::from_waker(&waker);
  42. loop {
  43. match f.as_mut().poll(&mut cx) {
  44. Poll::Pending => {
  45. let mut runnable = park.0.lock().unwrap();
  46. while !*runnable {
  47. runnable = park.1.wait(runnable).unwrap();
  48. }
  49. *runnable = false;
  50. }
  51. Poll::Ready(val) => return val,
  52. }
  53. }
  54. }