

#include "pthread.h"
#include "unistd.h"
#include "mythread.h"
#include "exception.h"
#include "stdio.h"
#include "debug.h"
#include "string.h"



typedef struct{
  myth_def *head;

}self_def;
static self_def g_self;


int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
				   void *(*start_routine) (void *), void *arg);



static void *p_thread(void *t){
  myth_def *th=(myth_def *)t;
  th->id=(size_t)pthread_self();
  DBG_INFO("func:%08lx start id=%d.\n",(size_t)th->func,th->id);
  try_{
    if(!th->func){
      throw_("th->func was null.");
    }
    th->func(th->arg);
  }catch_ {
    DBG_WARN("thread(%s)=%08lx failed.\n",th->name,(size_t)th->func);
    DBG_WARN("%s:%d err(%s)\n",exception()->file,exception()->line,exception()->log);
  }
  DBG_INFO("func:%08lx end.\n",(size_t)th->func);
  th->end=1;
  return 0;
}




pthread_t* myth_create(int (*func)(void *t),void *t,const char *name){
  myth_def *m=calloc(sizeof(myth_def),1);
  m->func=func;
  m->arg = t;
  if(name)
    strncpy(m->name, name, FUNC_NAME_LEN - 1);
  pthread_create(&m->th, NULL, p_thread, m);
  {
    self_def *s=&g_self;
    if(s->head==NULL){
      s->head=m;
    }else{
      myth_def *myth=s->head;
      while(myth->next){
        myth=myth->next;
      }
      myth->next=m;
      m->last=myth;
    }
  }
  return &m->th;
}


int myth_join(){
  self_def *s=&g_self;
  myth_def *myth=s->head;
  myth_def *old;
  while(myth){
    pthread_join(myth->th,NULL);
    old=myth;
    myth=myth->next;
    free(old);
  }
  s->head=NULL;
  return 0;
}



myth_def *myth_self(){
  self_def *s=&g_self;
  myth_def *myth=s->head;
  size_t id=(size_t)pthread_self();
  while(myth){
    if(myth->id==id){
      return myth;
    }
    myth=myth->next;
  }
  DBG_WARN("can not find myth.\n");
  return NULL;
}


