/**
 * @file   AXFIrqSignal.hpp
 * @brief  AXFIrqSignalクラスヘッダ
 *
 * @par    Programming Language
 *         C++
 */

#ifndef AXFIRQSIGNAL_HPP_
#define AXFIRQSIGNAL_HPP_

#include "AXFEvent.hpp"

class AXFObjectName;
class AXFConditionVariableInternal;
class AXFTask;
class AXFMailboxInternal;

/**
 * @class AXFIrqSignal
 * @brief ハードウェア・割り込みハンドラからアクタを起床させる機能を提供する
 *
 * @n     ハードウェア・割り込みハンドラから条件変数で起床するタスクを提供し、
 * @n     そのタスク・コンテキスト上で該当するアクタに AXFMailbox を使用して
 * @n     イベント通知を行う
 */
class AXFIrqSignal {
  AXFObjectName& m_name;
  AXFEvent_t m_eventId;
  AXFConditionVariableInternal* m_cond;
  AXFTask* m_thread;
  AXFMailboxInternal* m_mailbox;
  bool m_isInited;
  bool m_isActive;

 public:

  /**
   * @brief AXFIrqSingalコンストラクタ
   * @param [in] name アクタ名
   * @param [in] eventId イベントID
   */
  AXFIrqSignal(AXFObjectName& name, AXFEvent_t eventId,
               AXFConditionVariableInternal* cond = 0, AXFTask* task = 0);

  /**
   * @brief AXFIrqSingalデストラクタ
   */
  virtual ~AXFIrqSignal();

  /**
   * @brief  irqSignalの生成を行う
   */
  virtual bool create();

  /**
   * @brief  イベント通知を行う
   */
  virtual bool signal();

 private:
  // インスタンスのコピーは想定しない(Klockwork指摘対応:CL.FFM.ASSIGN)
  AXFIrqSignal& operator=(const AXFIrqSignal&) {
    return *this;
  }

  // インスタンスのコピーは想定しない(Klockwork指摘対応:CL.FFM.COPY)
  AXFIrqSignal(const AXFIrqSignal& obj)
      : m_name(obj.m_name),
        m_eventId(obj.m_eventId),
        m_cond(obj.m_cond),
        m_thread(obj.m_thread),
        m_mailbox(obj.m_mailbox),
        m_isInited(obj.m_isInited),
        m_isActive(obj.m_isActive) {
  }

  void *do_worker_sub();

  static void *do_worker(void *obj) {
    AXFIrqSignal *fIrqSignal = reinterpret_cast<AXFIrqSignal *>(obj);
    return fIrqSignal->do_worker_sub();
  }
};

#endif /* AXFIRQSIGNAL_HPP_ */
