C++ reimplementation of Python's threading.Event I've reimplemented in C++ the basic interface implemented by Python's threading.Event class using a mutex and condition variable. I've inlined functions rather than pasted both the header and source file. My reimplementation also skips the timeout argument to wait since I don't need it. The code appears to work through basic testing (test shown below reimplementation), but I'm particularly concerned about thread safety -- is using a mutex to protect isSet_ enough, or is there a way for a thread to get stuck waiting for an event that's already been set? Are there any other improvements I need to make?
Reimplementation:
#include &lt;mutex&gt;
#include &lt;condition_variable&gt;

class Event {
private:
    std::mutex isSetLock;
    bool isSet_ = false;
    std::mutex setTriggerLock;
    std::condition_variable setTrigger;
public:
    bool isSet () {
        isSetLock.lock ();
        bool isSetRet (isSet_);
        isSetLock.unlock ();
        return isSetRet;
    };
    void set () {
        isSetLock.lock ();
        isSet_ = true;
        isSetLock.unlock ();
        setTrigger.notify_all ();
    };
    void clear () {
        isSetLock.lock ();
        isSet_ = false;
        isSetLock.unlock ();
    };
    void wait () {
        if (!isSet ()) {
            std::unique_lock &lt;std::mutex&gt; setTriggerUniqueLock (setTriggerLock);
            setTrigger.wait (setTriggerUniqueLock);
        }
    };
};

Basic test:
#include &quot;Event.hpp&quot;
#include &lt;thread&gt;

class Test {
    Event event;
    void thread_ () {
        event.wait ();
    };
public:
    Test () {
        std::thread thread (&amp;Test::thread_, this);
        event.set ();
        thread.join ();
    };
};
int main () {
    Test test;
    // Should exit immediately
};
You can simplify things using RAII.
bool isSet () {
    isSetLock.lock ();
    bool isSetRet (isSet_);
    isSetLock.unlock ();
    return isSetRet;
};

Can be simplified to:
bool isSet () {
    std::lock_guard&lt;std::mutex&gt;  lockGuard(isSetLock);    // Calls lock.
    return isSet_;
};                                                        // Calls unlock
                                                          // in destructor.

Why do you have two different mutexes? There should only be a single one:
void wait () {
    if (!isSet ()) {
        std::unique_lock &lt;std::mutex&gt; setTriggerUniqueLock (setTriggerLock);
        setTrigger.wait (setTriggerUniqueLock);
    }
}

This should be:
    std::unique_lock &lt;std::mutex&gt; setTriggerUniqueLock(isSetLock);
    while (isSet()) {
       setTrigger.wait(setTriggerUniqueLock);
    }

Note: While the thread is paused (waiting) in the condition variable the mutex is unlocked (so other threads can still lock the mutex). The thread is only released from the condition variable (after a notify) when it has re-acquired the lock.
Note: You have to use while here (not if). After the thread is woken you need to retest the condition because another thread may have re-locked the isSet_ variable before this thread re-acquired the lock.
Note: The condition variable has this built in:
    std::unique_lock &lt;std::mutex&gt; setTriggerUniqueLock(isSetLock);
    setTrigger.wait(setTriggerUniqueLock, [&amp;](){return !isSet_WithoutNeedingToLockAsWeHaveTheLock()});

Note: After doing this your notify_all() should be on setTrigger.