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

  \author Satofumi KAMIMURA

  $Id: Thread.cpp 911 2009-05-20 11:29:16Z 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();
}
