//  $Id: UIThread.cxx,v 1.8 1999/09/13 21:35:30 yoonforh Exp $
/////////////////////////////////////////////////////////////////////////////
/*
 * Copyright (c) 1998-2002 Yoon Kyung Koo(yoonforh@yahoo.com).
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL YOON KYUNG KOO OR THE OTHER
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
/////////////////////////////////////////////////////////////////////////////
//
//  DESCRIPTION
//  	a Thread class implementation
//
///

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//  AUTHOR : Yoon Kyung Koo (yoonforh@yahoo.com)                           //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////

#include <iostream>
#include "Thread.hxx"

/**
 * Semaphore class
 *  semaphore wrapper class
 *  implementation
 */
#define THREAD_SCOPE 0
Semaphore::Semaphore(int value)
{
    int res=0;
    if ((res=::sema_init(&sem, value, USYNC_THREAD, NULL))<0)
	cerr << "sema_init:cannot initialize semaphore. "
	     << ::strerror(res) << endl;
}

Semaphore::~Semaphore()
{
    int res=0;
    if ((res=::sema_destroy(&sem))<0)
	cerr << "sema_destroy:cannot destroy semaphore. " 
	     << ::strerror(res) << endl;
}

/**
 * Mutex class
 *  mutex wrapper class
 *  implementation
 */
Mutex::Mutex()
{
    int res=0;
    if ((res=::mutex_init(&mutex, USYNC_THREAD, NULL))!=0)
	cerr << "mutex_init:cannot initialize mutex. "
	     << ::strerror(res) << endl;
}

Mutex::~Mutex()
{
    int res=0;
    if ((res=::mutex_destroy(&mutex))!=0)
	cerr << "mutex_destroy:cannot destroy mutex. "
	     << ::strerror(res) << endl;
}

/**
 * CondVar class
 *  condition variable wrapper class
 *  implementation
 */
CondVar::CondVar(Mutex& mutex):mutex(mutex)
{
    int res = 0;
    if ((res=::cond_init(&cv, USYNC_THREAD, NULL))!=0)
	cerr << "cond_init:cannot initialize cv. "
	     << ::strerror(res) << endl;
}

CondVar::~CondVar()
{
    int res=0;
    if ((res=::cond_destroy(&cv))!=0)
	cerr << "cond_destroy:Cannot destroy cv. "
	     << ::strerror(res) << endl;
}

/**
 * Thread class
 *  thread wrapper class
 *  implementation
 * NOTE
 *  the detach model of UI thread impl. is different from
 *  that of posix thread impl.
 *  posix thread uses cleanup routine but
 *  UI thread don't have such routine instead,
 *  can wait for any thread to terminate using thr_join.
 *  use joinAll() to elimnate non-detached thread problem
 * TO DO
 *  -. support for TSD(thread specific data)
 *  -. support for ThreadAttr
 */
// constructor
Thread::Thread(const string& name, int stackSize)
    : name(name),status(THREAD_STATUS_NORMAL),stackSize(stackSize),running(false)
{
/*
  if (::pthread_attr_init(&attr) !=0) {
  cerr << "pthread_attr_init:cannot initialize thread attribute. "
  << ::strerror(errno) << endl;
  status = THREAD_STATUS_FATAL;
  }
*/
    init();
}

// destructor
Thread::~Thread()
{
    cleanup();
}

// do nothing...
void
Thread::run()
{
#ifdef DEBUG
    cerr << "virtual Thread::run() called..." << endl;
#endif
}

// member functions

/**
 * init() : write codes what you want to do
 *      before thread start
 */
void
Thread::init()
{
#ifdef DEBUG
    cerr << "[virtual] init" << endl;
#endif
}

/**
 * cleanup() : write codes what you want to do
 *      after thread quit
 */
void
Thread::cleanup()
{
#ifdef DEBUG
    cerr << "[virtual] cleanup" << endl;
#endif
    // by default detach thread
    // this function assumes that this thread was running in non-detached mode
//  detach();
}
