Is accessing a tuple of tuples of pointers and a mutexes thread-safe
Quoting from the perfect answer to the question you linked:
However, if the parameter were const, then get would not be considered to provoke a data race with other const calls to get.
This is basically your answer. Make each and every get
call (on any tuple that's not completely protected by a mutex) on a const
tuple and you're safe.
This means your code as posted is not safe. Modify like so:
void baz(){ // vvvv just being explicit here auto const & tup = std::get<0>(static_cast<decltype(tuple) const &>(tuple)); std::lock_guard<std::mutex> lk(*std::get<2>(tup)); // Dereference std::get<0>(tup) and std::get<1>(tup), // use the pointed to objects at will, nothing else // Not ok, because it could interfer with the call in initialisation of tup of another thread // auto non_const_tup = std::get<0>(tuple)}
Currently the only solution I see is using a tuple like:
std::tuple< std::shared_pointer<std::mutex>, std::unique_pointer<std::tuple<Foo1*, Bar1*>> // Mutex and pointer to tuple for Foo2 and Bar2 >
The required const
will stick to everything (except pointer targets).