Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #![allow(dead_code)]
- use std::sync::{
- atomic::{AtomicU8, Ordering},
- Mutex,
- };
- /// Starts doing WorkA
- fn extern_lib_start_a() {}
- /// Starts doing WorkB
- fn extern_lib_start_b() {}
- /// Waits until no work is running
- fn extern_lib_wait() {}
- /// Result of last finished work. Undefined if work is running. Not thread safe.
- fn extern_lib_result() -> i32 {
- 0
- }
- #[repr(u8)]
- enum State {
- Idle = 0,
- WorkA = 1,
- WorkB = 2,
- }
- struct Foo {
- state: AtomicU8,
- handle: Mutex<i32>,
- }
- impl Foo {
- // Return immediately if not Idle
- fn work_a(&self) {
- let old_state = self.state.load(Ordering::Acquire);
- if old_state != State::Idle as u8 {
- // False positives OK.
- return;
- }
- let _lock = self.handle.lock();
- extern_lib_start_a();
- self.state.store(State::WorkA as u8, Ordering::Release);
- }
- fn work_b(&self) {
- let old_state = self.state.load(Ordering::Acquire);
- if old_state != State::Idle as u8 {
- // False positives OK.
- return;
- }
- let _lock = self.handle.lock();
- extern_lib_start_b();
- self.state.store(State::WorkB as u8, Ordering::Release);
- }
- fn finalize(&self) {
- let mut lock = self.handle.lock().unwrap();
- // If State == Idle, we return immediately and will not block the other
- // functions. If State != Idle, the other functions will detect that and
- // return immediately.
- if self.state.load(Ordering::Acquire) != State::Idle as u8 {
- extern_lib_wait();
- *lock = extern_lib_result();
- self.state.store(State::Idle as u8, Ordering::Release);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement