Is something like this valid:
std::vector<std::vector<int>> data;
std::shared_mutex m;
...
void Resize() {
// AreAllVectorsEmpty: std::all_of(data.begin(), data.end(), [](auto& v) { return v.empty(); }
if (!AreAllVectorsEmpty()) {
m.lock();
if (!AreAllVectorsEmpty()) {
data.resize(new_size);
}
m.unlock();
}
}
I am checking AreAllVectosEmpty() and then if condition succeeds, then taking lock and then again check for the same condition whether to do the resize.
Would this be thread safe? Resize is only called by one thread, but other threads manipulate elements of data.
Is it a requirement that AreAllVectorsEmpty have a memory fence or acquire semantics?
Edit: Other threads would ofcourse block when m.lock is acquired by Resize.
Edit: Let's also assume new_size is large enough that reallocation happens.
Edit: Update code for shared_mutex.
Edit: AreAllVectorsEmtpy is iterating over the data vector. Nobody else modifies data vector, but data[0], data[1] etc are modified by other threads. My assumption is since data[0]'s size variable is inside the vector and is a simple integer, it is safe to access data[0].size(), data[1].size() etc... in the Resize thread. AreAllVectorsEmpty is iterating over data and checking vector.empty().