mardi 2 juillet 2019

EventTask with std::condition_variable

Im trying to make a EventTask that calls a function passed in a loop.

I need it to wait to start then mark it as finished.

My problem is i dont know how to receive the arguments from my wait function to pass to the function that is called

As you can see the problem is in my taskFunc _event.wait should set the arguments to pass onto the function.

class Event
{
public:

    Event() : _signalled(false) {}

    virtual inline void notify(){
        std::unique_lock<std::mutex> lock(_mutex);
        _signalled = true;
        _condvar.notify_one();
    }

    virtual inline void wait(){
        std::unique_lock<std::mutex> lock(_mutex);
        _condvar.wait(lock, [&] { return _signalled; });
        _signalled = false;

        stop();
    }

    virtual inline void stop(){
        std::unique_lock<std::mutex> lock(_mutex);
        _signalled = false;
    }

private:

    std::mutex _mutex;
    std::condition_variable _condvar;
    bool _signalled;
};

template <class T>
class EventArg : public Event
{
public:

    virtual inline void notify(T arg){
        Event::notify();
        this->arg = arg;
    }

    virtual inline void wait(T& arg){
        Event::wait();
        arg = this->arg;
    }

private:
    T arg;
};

template<class... Args>
class EventTask
{
public:
    EventTask(std::function<void(Args...)> func) : m_Function(func), m_Run(true), m_thread(&taskFunc, this) {}

    void notify(Args&& ...Params) { 
        _Event.notify(std::forward<Args>(Params)...); }

    void wait() { 
        _EventFinished.wait(); }

    void stop() {
        m_stop = true;
        _Event.stop();
    }

private:
    void taskFunc()
    {
        void* pArg = nullptr;
        while (m_Run){
            _Event.wait(pArg);
            m_Function(std::forward<Args>(Params)...);
            _EventFinished.notify();
        }
    }

private:
    std::function<void(Args...)> m_Function;
    bool m_Run;
    std::thread m_thread;
    EventArg<Args...> _Event;
    Event _EventFinished;
};

Aucun commentaire:

Enregistrer un commentaire