/*!
  \file
  \brief スレッド処理のラッパー

  \author Satofumi KAMIMURA

  $Id: Thread.cpp 1977 2012-04-05 08:04:51Z satofumi $
*/

#include "Thread.h"
#include <QThread>
#include <limits>

using namespace qrk;
using namespace std;


namespace
{
    class ThreadWrapper : public QThread
    {
        int (*function_)(void *);
        void* args_;
        int times_;
        int return_value_;


    public:

        ThreadWrapper(int (*function)(void *), void* args)
            : function_(function), args_(args), times_(1), return_value_(-1)
        {
        }


        void setTimes(int times)
        {
            times_ = times;
        }


        void run(void)
        {
            for (int i = 0; i < times_; ++i) {
                return_value_ = function_(args_);
                usleep(1);
            }
        }


        int returnValue(void)
        {
            return return_value_;
        }
    };
}


struct Thread::pImpl
{
    ThreadWrapper thread_;


    pImpl(int (*fn)(void *), void* args) : thread_(fn, args)
    {
    }
};


Thread::Thread(int (*fn)(void *), void* args) : pimpl(new pImpl(fn, args))
{
}


Thread::~Thread(void)
{
    pimpl->thread_.wait();
}


void Thread::run(int times)
{
    pimpl->thread_.setTimes((times == Infinity)
                            ? numeric_limits<int>::max() : times);
    pimpl->thread_.start();
}


void Thread::stop(void)
{
    pimpl->thread_.terminate();
}


int Thread::wait(void)
{
    pimpl->thread_.wait();
    return pimpl->thread_.returnValue();
}


bool Thread::isRunning(void) const
{
    return pimpl->thread_.isRunning();
}
