HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

C++11 class similar to .Net's ManualResetEvent, but without the ability to "reset"

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
withouttheclassbutmanualreseteventnetsimilarresetability

Problem

The goal is to block all threads that call WaitOne(). When Set() is called, those threads continue. Any calls to WaitOne(), after Set(), return immediately. The challenge is to make sure that all calls to WaitOne() are either "before" or "after" the call to Set(), so that no threads see _state false, but miss the notify_all. I'm looking for feedback on performance and correctness.

#ifndef NO_RESET_EVENT_H
#define NO_RESET_EVENT_H

#include 
#include 

class NoResetEvent
{
public:
    NoResetEvent() : state(false) {}
    NoResetEvent(const NoResetEvent& other) = delete;

    void WaitOne() {
        std::unique_lock lock(sync);
        while (!state) {
            underlying.wait(lock);
        }
    }

    void Set() {
        std::unique_lock lock(sync);
        state = true;
        underlying.notify_all();
    }

private:
    std::condition_variable underlying;
    std::mutex sync;
    volatile bool state;
};

#endif

Solution

Looks good.

The only thing I would change is:

volatile bool _state;


into

std::atomic  _state;


The issue with volatile is that it does not universally provide that guarantee that updates are visible to all threads (which std::atomic does).

Could simplify the wait() call.

while (!_state) {
        _underlying.wait(lock);
    }

    // could be:
    _underlying.wait(lock,[&state](){return state;});


Personally I don't like prefix '_' on identifiers. The rules for using '_' as a prefix are complicated. Even if you know the rules not everybody that reads your code will.

Code Snippets

volatile bool _state;
std::atomic<bool>  _state;
while (!_state) {
        _underlying.wait(lock);
    }

    // could be:
    _underlying.wait(lock,[&state](){return state;});

Context

StackExchange Code Review Q#75606, answer score: 7

Revisions (0)

No revisions yet.