common taskScheduler: fix a synchronization data race.

std mutex shouldn't be used among threads. behavior is unexpected by implmentation.

This resolves it by introducing conditional value.
This commit is contained in:
Subhransu Mohanty 2020-11-10 16:43:19 +09:00 committed by Hermet Park
parent d1d54e8b8f
commit c2e1583e94

View file

@ -23,6 +23,7 @@
#define _TVG_TASK_SCHEDULER_H_ #define _TVG_TASK_SCHEDULER_H_
#include <mutex> #include <mutex>
#include <condition_variable>
#include "tvgCommon.h" #include "tvgCommon.h"
namespace tvg namespace tvg
@ -41,21 +42,24 @@ struct TaskScheduler
struct Task struct Task
{ {
private: private:
mutex mtx; mutex mtx;
bool working = false; condition_variable cv;
bool ready{true};
bool pending{false};
public: public:
virtual ~Task() = default; virtual ~Task() = default;
void done() void done()
{ {
if (!working) return; if (!pending) return;
if (TaskScheduler::threads() > 0) { if (TaskScheduler::threads() > 0) {
mtx.lock(); unique_lock<mutex> lock(mtx);
working = false; while (!ready) cv.wait(lock);
mtx.unlock();
} }
pending = false;
} }
protected: protected:
@ -66,14 +70,20 @@ private:
{ {
run(tid); run(tid);
if (TaskScheduler::threads() > 0) mtx.unlock(); if (TaskScheduler::threads() > 0) {
{
lock_guard<mutex> lock(mtx);
ready = true;
}
cv.notify_one();
}
} }
void prepare() void prepare()
{ {
if (TaskScheduler::threads() > 0) { if (TaskScheduler::threads() > 0) {
working = true; ready = false;
mtx.lock(); pending = true;
} }
} }