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

  \author Satofumi KAMIMURA

  $Id: Lock.cpp 1811 2010-04-30 16:12:05Z satofumi $
*/

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

using namespace qrk;


struct Lock::pImpl
{
    friend class ConditionVariable;

    QMutex mutex_;
};


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


Lock::~Lock(void)
{
}


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


bool Lock::tryLock(void)
{
    return pimpl->mutex_.tryLock();
}


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


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

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

  \author Satofumi KAMIMURA

  $Id: Lock.cpp 1811 2010-04-30 16:12:05Z 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;
}
