Name for "thing" that waits thread on boolean condition

I started with goal of efficiently waiting a thread on an atomic boolean.

I didn’t see how to do that, but I found Condvar and then Condvar based Semaphore implementations. I don’t think Semaphore’s really do what I want… I want just a flag that when set with let other thread wake up. I don’t need/want to maintain any counting state between waits and notifies.

Anyway, what I’ve come up with follows and seems to be working well for me. My question… what should this be called? At the moment I’m calling BooleanSemaphore since I started with an existing semaphore implementation. But maybe there’s already an existing name for “wait on boolean flag”? Does semaphore imply some sort of count being maintained between the waits and the notifies?

use parking_lot::{Mutex, Condvar};
use std::time::Duration;

#[derive(Debug)]
pub struct BooleanSemaphore {
    mutex: Mutex<bool>,
    cvar: Condvar,
}

impl BooleanSemaphore {
    pub fn new (value: bool) -> Self {
        BooleanSemaphore {
            mutex: Mutex::new(value),
            cvar: Condvar::new(),
        }
    }

    pub fn wait(&self) {
        let mut value = self.mutex.lock();
        while !(*value) {
            self.cvar.wait(&mut value);
        }
    }

    pub fn wait_for(&self, timeout: Duration) {
        let mut value = self.mutex.lock();
        while !(*value) {
            let _ = self.cvar.wait_for(&mut value, timeout);
        }
    }

    pub fn set_ready(&self, ready: bool) {
        let mut value = self.mutex.lock();
        *value = ready;
        self.cvar.notify_all();
    }
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.47s

This looks like .Net’s ManualResetEvent without the reset.

One implementation note: your wait_for will not wait for the correct time if there are spurious wakeups (which is what I assume the loop is to protect against), although it looks like the API to fix that is still unstable.

1 Like

Thanks, yes that looks very similar. I’ll name after that.

Thanks again. I think this is what I should really have done:

pub fn wait_for(&self, timeout: Duration) {
  let mut value = self.mutex.lock();
  while !(*value) {
    if self.cvar.wait_for(&mut value, timeout).timed_out() {
      return
    }
  }
}

There is also Python’s threading.Event. Which also looks a lot like Java’s Object.wait()/Object.notify() pair.

1 Like