I have a thread that is doing "work", it is supposed to report progress when conditional variable notifies it. This thread is waiting for conditional variables.
Other thread is waiting for a x amount of milliseconds and then notifies conditional variable to proceed.
I have 5 conditional variables (this is an exercise for school) and once each gets notified work progress is supposed to be reported:
Problem im having is that thread 2, the one that is supposed to notify thread 1, goes through all 5 checkPoints and notifies only once in the end. So I end up in a situation where progress is at 20% in the end and thread 1 is waiting for another notify but thread 2 has finished all notifies.
Where is flaw in my implementation of this logic? Code below:
#include <condition_variable>
#include <functional>
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
class Program {
public:
  Program() {
    m_progress = 0;
    m_check = false;
  }
  bool isWorkReady() { return m_check; }
  void loopWork() {
    cout << "Working ... : " << endl;
    work(m_cv1);
    work(m_cv2);
    work(m_cv3);
    work(m_cv4);
    work(m_cv5);
    cout << "\nFinished!" << endl;
  }
  void work(condition_variable &cv) {
    unique_lock<mutex> mlock(m_mutex);
    cv.wait(mlock, bind(&Program::isWorkReady, this));
    m_progress++;
    cout << " ... " << m_progress * 20 << "%" << endl;
    m_check = false;
  }
  void checkPoint(condition_variable &cv) {
    lock_guard<mutex> guard(m_mutex);
    cout << " < Checking >" << m_progress << endl;
    this_thread::sleep_for(chrono::milliseconds(300));
    m_check = true;
    cv.notify_one();
  }
  void loopCheckPoints() {
    checkPoint(m_cv1);
    checkPoint(m_cv2);
    checkPoint(m_cv3);
    checkPoint(m_cv4);
    checkPoint(m_cv5);
  }
private:
  mutex m_mutex;
  condition_variable m_cv1, m_cv2, m_cv3, m_cv4, m_cv5;
  int m_progress;
  bool m_check;
};
int main() {
  Program program;
  thread t1(&Program::loopWork, &program);
  thread t2(&Program::loopCheckPoints, &program);
  t1.join();
  t2.join();
  return 0;
}
 
     
    