Everywhere I read I see strong recommendations not to use relaxed memory order, I wonder whether the following piece of code is one of this exceptions in which this will work, or there are any ramifications I'm not seeing.
class SessionHolder {
public:
void set_session(std::shared_ptr<Session> session) {
std::atomic_store_explicit(&_session, session, std::memory_order_relaxed);
}
std::shared_ptr<Session> get_session() const {
return std::atomic_load_explicit(&_session, std::memory_order_relaxed);
}
private:
std::shared_ptr<Session> _session;
};
In principle, when I do a get_session, I don't care which session I'm getting as long as it is a session or nullptr. But if another thread does a store (which happens rarely), I would like to eventually get that value within a reasonable delay.
- As I understand, it is not even guaranteed that I would get that value, just that I will get a value that was stored there at some point in time, but I could always get nullptr.
- In practice seems to work, can I expect it to fail (always retrieving nullptr) in some situations/platform specifically?
- Can I adjust the memory order in the store operation only to fix this? e.g.
memory_order_releasewould spread the changes to the other thread?
More context on how this class is used:
Basically, I have some sort of stream that is continuously producing data. At a certain point a client process may connect (start a session) and start listening to this data. The producer thread is continuously writing to the stream, if there is no active session the data is discarded, else sent to the client. Another thread, at certain point (not often), when a client connects reaches to this stream and sets the session.
The producer thread must have as little contention as possible, even if that means missing a few messages.