2

Note, this is a followup to: What are the options for safely modifying and reading a boolean across multiple threads and cpus?

I have some C++ code that contains roughly this logic:

class wrapper_info {
public:
        bool isConnected();
        void connectedHandler();
        void disconnectedHandler();
protected:
        std::atomic<bool> _connected;
}

void wrapper_info::connectedHandler() {
        _connected.store(true, std::memory_order_relaxed);
}

void wrapper_info::disconnectedHandler() {
        _connected.store(false, std::memory_order_relaxed);
}

bool wrapper_info::isConnected() {
        return _connected.load(std::memory_order_relaxed);
}

They are called in the following way:

Thread 1, 2, 3: isConnected()

Thread 2: connectedHandler() when the connection is initiated.

Thread 3 disconnectedHandler() when the connection is broken.

Is it sufficient to use memory_order_relaxed? It is my understanding that I would only need others like memory_order_release and memory_order_acquire when I want to ensure that other operations around it are seen by other threads. But I am just setting/reading a value. Thank you lots.

someone serious
  • 197
  • 1
  • 1
  • 8
  • 4
    As long as there are no other operations that would depend on the value being in expected state, yes, you can use relaxed setting here. Although, it might be tricky to prove, so unless your fences are really killing performance (how often are you going through reconnection cycle?), sequential model is easiest to understand and reason about. – SergeyA Sep 17 '21 at 18:13
  • 6
    Usually you have to dig a little deeper - *why* are you setting and reading this value? If, for instance, you are testing it to see whether some global resource is available, then you need a barrier to ensure that your access of the resource doesn't get reordered before the test. It's not a question you can answer in isolation. – Nate Eldredge Sep 17 '21 at 18:31
  • 3
    On another note, how will you do this without having a race? What happens if thread 1 tests `isConnected()` and goes on to do some stuff with the connection, but thread 3 disconnects the object before thread 1 actually gets started? – Nate Eldredge Sep 17 '21 at 18:34
  • Agreed with Nate; you maybe want some kind of reference-count for how many threads are currently wanting to keep the connection alive, and instead of checking `isConnected()`, a thread would increment that counter. If it had previously been zero, then you'd have to figure out whether a disconnect was in progress or had already happened. (Or hmm, even that's not sufficient; two threads could both try to claim, and the 2nd one could see the ref count go from 1 to 2 even though it had earlier been zero. So I guess before starting a disconnect, cmpxchg it to -999 or INT_MIN.) – Peter Cordes Sep 17 '21 at 21:55

0 Answers0