So I just found out that it's legal to signal a condition variable if you're not holding the lock in c++11. That seems to open the door to some nasty race condition:
std::mutex m_mutex;
std::condition_variable m_cv;
T1:
std::unique_lock<std::mutex> lock(m_mutex);
m_cv.wait(lock, []{ return !is_empty(); });
T2:
generate_data();
m_cv.notify();
Is it guaranteed that T1 will never end up in a situation where we check is_empty() first (it returning true), then getting preempted by T2 which creates some data and signals the condition variable before we can actually wait on it?
If this is guaranteed to work (I'd guess so, otherwise it would seem like an intentionally bad API design), how is this actually implemented for say linux and stdlibc++
? Seems we'd need another lock to avoid this situation.