SHARE
TWEET

Untitled

a guest Apr 24th, 2019 53 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #![allow(dead_code)]
  2. use std::sync::{
  3.     atomic::{AtomicU8, Ordering},
  4.     Mutex,
  5. };
  6.  
  7. /// Starts doing WorkA
  8. fn extern_lib_start_a() {}
  9.  
  10. /// Starts doing WorkB
  11. fn extern_lib_start_b() {}
  12.  
  13. /// Waits until no work is running
  14. fn extern_lib_wait() {}
  15.  
  16. /// Result of last finished work. Undefined if work is running. Not thread safe.
  17. fn extern_lib_result() -> i32 {
  18.     0
  19. }
  20.  
  21. #[repr(u8)]
  22. enum State {
  23.     Idle = 0,
  24.     WorkA = 1,
  25.     WorkB = 2,
  26. }
  27.  
  28. struct Foo {
  29.     state: AtomicU8,
  30.     handle: Mutex<i32>,
  31. }
  32.  
  33. impl Foo {
  34.     // Return immediately if not Idle
  35.     fn work_a(&self) {
  36.         let old_state = self.state.load(Ordering::Acquire);
  37.         if old_state != State::Idle as u8 {
  38.             // False positives OK.
  39.             return;
  40.         }
  41.  
  42.         let _lock = self.handle.lock();
  43.         extern_lib_start_a();
  44.         self.state.store(State::WorkA as u8, Ordering::Release);
  45.     }
  46.  
  47.     fn work_b(&self) {
  48.         let old_state = self.state.load(Ordering::Acquire);
  49.         if old_state != State::Idle as u8 {
  50.             // False positives OK.
  51.             return;
  52.         }
  53.  
  54.         let _lock = self.handle.lock();
  55.         extern_lib_start_b();
  56.         self.state.store(State::WorkB as u8, Ordering::Release);
  57.     }
  58.  
  59.     fn finalize(&self) {
  60.         let mut lock = self.handle.lock().unwrap();
  61.  
  62.         // If State == Idle, we return immediately and will not block the other
  63.         // functions. If State != Idle, the other functions will detect that and
  64.         // return immediately.
  65.         if self.state.load(Ordering::Acquire) != State::Idle as u8 {
  66.             extern_lib_wait();
  67.             *lock = extern_lib_result();
  68.             self.state.store(State::Idle as u8, Ordering::Release);
  69.         }
  70.     }
  71. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top