// hilo.cpp - Definición de la clase CHilo
#include "hilo.h"

// Constructor
CHilo::CHilo(string nom, pthread_attr_t *attr) :
m_nombreHilo(nom), m_attr(attr)
{
  m_idHilo.p = 0; 
}

// Destructor
CHilo::~CHilo()
{
  if (m_idHilo.p) // si el hilo existe, finalizarlo
  {
    int cod = pthread_cancel(m_idHilo); //terminar el hilo m_idHilo
    if (cod) throw(string("error: pthread_cancel"));
    m_idHilo.p = 0;
  }
}

// Crear el hilo que ejecutará el método static ejec_hilo,
// el cual recibe como argumento this.
void CHilo::iniciar()
{
  if (m_idHilo.p) return;
  int cod = pthread_create(&m_idHilo, m_attr, ejec_hilo, this);
  if (cod) throw(string("error: pthread_create"));
}

// El método ejec_hilo invoca a fnHilo, método virtual puro
// que el usuario debe redefinir para escribir el código que
// ejecutará el hilo.
void *CHilo::ejec_hilo(void *arg)
{
  CHilo *pObj = reinterpret_cast<CHilo *>(arg); // this
  return pObj->fnHilo();
}

// Método que esperará a que m_idHilo finalice
void *CHilo::esperar_finalizacion()
{
  void *vr;
  int cod = pthread_join(m_idHilo, &vr);
  if (cod) throw(string("error: pthread_join"));
  m_idHilo.p = 0;
  return vr;
}

string CHilo::obtener_nombre() const
{
  return m_nombreHilo;
}

void CHilo::asignar_nombre(string nom)
{
  m_nombreHilo = nom;
}

void *CHilo::obtener_id() const
{
  return m_idHilo.p;
}

void CHilo::asignar_atributos(pthread_attr_t *attr)
{
  m_attr = attr;
}
