#include "nixsys.h" #include "thread.h" #include "semaphore.h" using namespace std ; using namespace n2nc ; n2nc::sync::Semaphore g_sem(0); void* fun1(void *arg1){ cerr << "fun1 callled with args: " << (char*)arg1 ; cerr << " Thread name: " << n2nc::sync::Thread::getCurrent().toString() << endl ; sleep(3); /* NOTE the possible race condition */ g_sem.post(); return (void*)"fun1" ; } int fun1_exit(void* arg1){ cerr << "fun1 exited with args: " << (char*)arg1 ; cerr << " Thread name: " << n2nc::sync::Thread::getCurrent().toString() << endl ; } class myclass1 : public n2nc::sync::Thread { virtual void* entry_point(){ cerr << "myclass1 callled with args: " << (char*)this->m_args ; cerr << " Thread name: " << n2nc::sync::Thread::getCurrent().toString() << endl ; sleep(6); return (void*)"myclass1" ; } virtual int exit_point(){ /* NOTE HERE we avoid race condition because the thread has already terminated its routine and saved returns values. */ g_sem.post(); } }; int main(int argc, char *argv[]){ void *myretval1,*myretval2 ; n2nc::sync::Thread::init(); n2nc::sync::Thread *t1 = new n2nc::sync::InlineThread(&fun1); n2nc::sync::Thread *t2 = new myclass1() ; n2nc::sync::Thread *t3 = new n2nc::sync::InlineThread(&fun1,&fun1_exit); t1->setName("fun1 thread name"); t2->setName("myclass1 thread name"); t3->setName("fun1 thread name, with exit point callback"); t1->run((void*)"args to function fun1"); t2->run((void*)"args to class myclass1"); t3->run((void*)"args to function fun1 with callback"); /* wait the 2 threads termination through a global semaphore */ g_sem.wait(); g_sem.wait(); g_sem.wait(); /* t1->wait(&myretval1); t2->wait(&myretval2);*/ cerr << (char*)t1->getRetVal() << endl ; cerr << (char*)t2->getRetVal() << endl ; cerr << (char*)t3->getRetVal() << endl ; return EXIT_SUCCESS; }