/*!
  \file
  \brief ロッククラス

  \author Satofumi KAMIMURA

  $Id: Lock.cpp 1424 2009-10-19 12:21:34Z satofumi $
*/

#include "Lock.h"
#include <QMutex>

using namespace qrk;


struct Lock::pImpl
{
  friend class ConditionVariable;

  QMutex mutex_;


  ~pImpl(void)
  {
    mutex_.unlock();
  }
};


Lock::Lock(void) : pimpl(new pImpl)
{
}


Lock::~Lock(void)
{
}


void Lock::lock(void)
{
  pimpl->mutex_.lock();
}


void Lock::unlock(void)
{
  pimpl->mutex_.unlock();
}


//////////////////////////////////////////////////////////////////////
/*!
  \file
  \brief 条件変数

  Lock::pImpl のメンバ変数を操作するために、Lock.cpp で実装してある

  \author Satofumi KAMIMURA

  $Id: Lock.cpp 1424 2009-10-19 12:21:34Z satofumi $
*/

#include <QWaitCondition>


struct ConditionVariable::pImpl
{
  QWaitCondition condition_;
  bool is_waiting_;


  pImpl(void) : is_waiting_(false)
  {
  }
};


ConditionVariable::ConditionVariable(void) : pimpl(new pImpl)
{
}


ConditionVariable::~ConditionVariable(void)
{
}


bool ConditionVariable::isWaiting(void)
{
  return pimpl->is_waiting_;
}


void ConditionVariable::wakeup(void)
{
  pimpl->is_waiting_ = false;
  pimpl->condition_.wakeOne();
}


void ConditionVariable::wakeupAll(void)
{
  pimpl->is_waiting_ = false;
  pimpl->condition_.wakeAll();
}


bool ConditionVariable::wait(Lock* lock, int timeout)
{
  if (pimpl->is_waiting_ == true) {
    return false;
  }
  pimpl->is_waiting_ = true;

  bool ret = false;
  if (timeout == NoTimeout) {
    ret = pimpl->condition_.wait(&lock->pimpl->mutex_);

  } else {
    ret = pimpl->condition_.wait(&lock->pimpl->mutex_, timeout);
  }
  return ret;
}
