Listing 1: The technique
#include <pthread.h>
struct Thread {
Thread (const pthread_t &pt) : pt (pt) {};
void join () { pthread_join (pt, 0); };
private:
pthread_t pt;
};
struct FunData {
typedef void * (*ThreadEntryPoint) (void *);
FunData (const ThreadEntryPoint tep)
: thread_entry_point (tep) {};
ThreadEntryPoint thread_entry_point;
};
template <typename Arg1>
class FunWrapper1 {
struct Data : public FunData {
typedef void (*FunPtr) (Arg1);
Data (FunPtr fun_ptr, Arg1 arg1)
: FunData (&Data::thread_entry_point),
fun_ptr (fun_ptr),
arg1 (arg1) {};
private:
FunPtr fun_ptr;
Arg1 arg1;
static void * thread_entry_point (void *arg);
};
public:
typedef void (*FunPtr) (Arg1);
FunWrapper1 (FunPtr fun_ptr) : fun_ptr(fun_ptr) {};
Thread operator() (Arg1 arg1) {
Data data(fun_ptr, arg1);
return do_spawn (data);
};
private:
FunPtr fun_ptr;
};
template <typename Arg1>
void * FunWrapper1<Arg1>::Data::thread_entry_point (void *arg) {
const Data *data = reinterpret_cast<const Data*> (arg);
(*data->fun_ptr)(data->arg1);
return 0;
}
Thread do_spawn (const FunData &data) {
pthread_t pt;
pthread_create (&pt, 0, *data.thread_entry_point,
(void *)&data);
return pt;
}
template <typename Arg1>
FunWrapper1<Arg1> spawn (void (*fun_ptr)(Arg1)) {
return FunWrapper1<Arg1>(fun_ptr);
}
End of Listing