Program Listing for File HsmEventDispatcherSTD.hpp

Return to documentation for file (include/hsmcpp/HsmEventDispatcherSTD.hpp)

// Copyright (C) 2021 Igor Krechetov
// Distributed under MIT license. See file LICENSE for details

#ifndef HSMCPP_HSMEVENTDISPATCHERSTD_HPP
#define HSMCPP_HSMEVENTDISPATCHERSTD_HPP

#include <chrono>
#include <map>
#include <thread>

#include "HsmEventDispatcherBase.hpp"
#include "os/ConditionVariable.hpp"

namespace hsmcpp {

class HsmEventDispatcherSTD : public HsmEventDispatcherBase {
private:
    struct RunningTimerInfo {
        std::chrono::time_point<std::chrono::steady_clock> startedAt;
        std::chrono::time_point<std::chrono::steady_clock> elapseAfter;
    };

public:
    // cppcheck-suppress misra-c2012-17.8 ; false positive. setting default parameter value is not parameter modification
    static std::shared_ptr<HsmEventDispatcherSTD> create(const size_t eventsCacheSize = DISPATCHER_DEFAULT_EVENTS_CACHESIZE);

    void emitEvent(const HandlerID_t handlerID) override;

    bool start() override;

    void stop() override;

    void join();

protected:
    explicit HsmEventDispatcherSTD(const size_t eventsCacheSize);

    virtual ~HsmEventDispatcherSTD();

    bool deleteSafe() override;
    void startTimerImpl(const TimerID_t timerID, const unsigned int intervalMs, const bool isSingleShot) override;
    void stopTimerImpl(const TimerID_t timerID) override;

    void notifyDispatcherAboutEvent() override;
    void doDispatching();

    void notifyTimersThread();
    void handleTimers();

private:
    std::thread mDispatcherThread;
    std::thread mTimersThread;
    // NOTE: ideally it would be better to use a semaphore here, but there are no semaphores in C++11
    ConditionVariable mEmitEvent;
    ConditionVariable mTimerEvent;
    bool mNotifiedTimersThread = false;
    std::map<TimerID_t, RunningTimerInfo> mRunningTimers; // protected by mRunningTimersSync
};

}  // namespace hsmcpp

#endif  // HSMCPP_HSMEVENTDISPATCHERSTD_HPP