Synchronized variable access in C++

I’m working with an API for a closed source library that comes with a recommendation of using two separate threads when passing it data in order to ensure that the data pipelines are never empty. I’ve been doing it for a while but recently we had a lot of stability issues. After some digging I tried to rewrite the two threads into one that multiplexed the calls instead and suddenly stability was back again. I think that if you recommend that people access your API via threads it would be nice to indicate that some calls aren’t thread safe, but no.

I decided to design a generic type that would allow synchronized access to any kind of variable while utilizing RAII to ensure that it is unlocked automatically. The task turned out to be a little more complicated than I first expected but after some trial and error I came up with a solution that I found had a good functionality/aesthetic ratio.

template <typename T>
class SynchronizedVariable : public boost::non_copyable {
public:
    class Accessor {
    public:
        T* operator->() {
            return m_variable;
        }

        const T* operator->() const {
            return m_variable;
        }

    private:
        Accessor(const boost::recursive_mutex::scoped_lock& lock, T* variable) :
            m_lock(lock),
            m_variable(variable) { }

        const boost::recursive_mutex::scoped_lock& m_lock;
        T* m_variable;

        friend class SynchronizedVariable<T>;
    };

    SynchronizedVariable(const T& variable) :
        m_mutex(),
        m_variable(variable) { }

    SynchronizedVariable() :
        m_mutex(),
        m_variable() { }

    const Accessor get() const {
        return Accessor(m_mutex, &m_variable);
    }

    Accessor get() {
        return Accessor(m_mutex, &m_variable);
    }

private:
    mutable boost::recursive_mutex m_mutex;
    T m_variable;
};

SynchronizedVariable is the actual container for the variable and you can either pass it a constant reference to an existing instance which will be copied or create a new empty instance. The idea is that you should not be able to retain an external copy which can be accessed unprotected. It is of course possible to access the original instance if the variable is copied but this is a limited case of programming error.

Subsequent accesses to the variable must go through an instance of the SynchronizedVariable<T>::Accessor object which ensures that the variable is protected by a mutex and that it is automatically unlocked when the accessor goes out of scope. It is of course possible to add lock/unlock methods to it so that the user can limit the scope of the lock. Personally I try to limit all my scopes as much as possible, especially in areas of code which is executed frequently and during performance sensitive moments.

Accessor is storing the variable as a pointer rather than a reference. The reasoning behind this is that operator-> has to return a pointer so storing a reference does not make a lot of sense. There is also a lot of mutex locking/unlocking going on if you instantiate the accessor in frequently called small scopes so be prepared to dust off gprof if you suspect that this is the case.