// GlibThread.hh --- GlibThread class
//
// Copyright (C) 2002, 2005, 2007, 2008, 2012 Rob Caelers & Raymond Penners
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#include "GlibThread.hh"

#include <glib.h>

Thread::Thread(Runnable *runnable, bool autodelete)
{
  thread_handle = NULL;
  this->runnable = runnable;
  this->autodelete = autodelete;
}

Thread::Thread(bool autodelete)
{
  thread_handle = NULL;
  this->runnable = NULL;
  this->autodelete = autodelete;
}

Thread::~Thread()
{
  wait();
}

void
Thread::start()
{
  if (thread_handle == NULL)
    {
      GError *error = NULL;

#if GLIB_CHECK_VERSION(2, 31, 18)
      thread_handle = g_thread_try_new("workrave", thread_handler, this, &error);
#else
      thread_handle = g_thread_create(thread_handler, this, TRUE, &error);
#endif
      if (error != NULL)
        {
          g_error_free(error);
        }
    }
}

void
Thread::wait()
{
  if (thread_handle != NULL)
    {
      g_thread_join(thread_handle);
      thread_handle = NULL;
    }
}

void
Thread::run()
{
  if (runnable != NULL)
    {
      runnable->run();
    }
}

void
Thread::internal_run()
{
  run();
  thread_handle = NULL;
}

gpointer
Thread::thread_handler(gpointer data)
{
  Thread *t = (Thread *)data;
  if (t != NULL)
    {
      t->internal_run();
      if (t->autodelete)
        {
          delete t;
        }
    }

  return 0;
}
