blob: ae61c0a5155998f526fde72f9043a5f82ce0c49d [file] [log] [blame]
// (C) Copyright Christian Bienia 2007
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0.
//
// file : Thread.cpp
// author : Christian Bienia - cbienia@cs.princeton.edu
// description : A C++ thread
#if defined(HAVE_CONFIG_H)
# include "config.h"
#endif
#if defined(HAVE_LIBPTHREAD)
# include <pthread.h>
#else //default: winthreads
# include <windows.h>
# include <process.h>
#endif //HAVE_LIBPTHREAD
#include <typeinfo>
#include "Thread.h"
namespace threads {
#if defined(HAVE_LIBPTHREAD)
// Unfortunately, thread libraries such as pthreads which use the C
// calling convention are incompatible with C++ member functions.
// To provide an object-oriented thread interface despite this obstacle,
// we make use of a helper function which will wrap the member function.
extern "C" {
static void *thread_entry(void *arg) {
Runnable *tobj = static_cast<Runnable *>(arg);
tobj->Run();
return NULL;
}
}
#else //default: winthreads
extern "C" {
unsigned __stdcall thread_entry(void *arg) {
Runnable *tobj = static_cast<Runnable *>(arg);
tobj->Run();
return NULL;
}
}
#endif //HAVE_LIBPTHREAD
//Constructor, expects a threadable object as argument
Thread::Thread(Runnable &_tobj) : tobj(_tobj) {
#if defined(HAVE_LIBPTHREAD)
if(pthread_create(&t, NULL, &thread_entry, (void *)&tobj)) {
ThreadCreationException e;
throw e;
}
#else //default: winthreads
t = (void *)_beginthreadex(NULL, 0, &thread_entry, (void *)&tobj, 0, &t_id);
if(!t) {
ThreadCreationException e;
throw e;
}
#endif //HAVE_LIBPTHREAD
}
//Wait until Thread object has finished
void Thread::Join() {
Stoppable *_tobj;
bool isStoppable = true;
//call Stop() function if implemented
try {
_tobj = &dynamic_cast<Stoppable &>(tobj);
} catch(std::bad_cast e) {
isStoppable = false;
}
if(isStoppable) {
_tobj->Stop();
}
#if defined(HAVE_LIBPTHREAD)
pthread_join(t, NULL);
#else //default: winthreads
WaitForSingleObject(t, INFINITE);
CloseHandle(t);
#endif //HAVE_LIBPTHREAD
}
} //namespace threads