-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPThreadCreateVarArg.hpp
More file actions
executable file
·54 lines (43 loc) · 1.34 KB
/
PThreadCreateVarArg.hpp
File metadata and controls
executable file
·54 lines (43 loc) · 1.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#ifndef PTWRAPPER_H
#define PTWRAPPER_H
#include <pthread.h>
#include <assert.h>
#include <tuple>
namespace incyc {
template <int...>
struct Sequence {};
template <int N, int... S>
struct Gens : Gens<N-1, N-1, S...> {};
template <int... S>
struct Gens<0, S...> { typedef Sequence<S...> type; };
template <typename T, typename R, typename... ATs>
class Call {
T *const obj;
R (T::*fp)(ATs...);
std::tuple<ATs...> params;
public:
Call(T *o, R (T::*mem)(ATs...), std::tuple<ATs...> p) : obj(o), fp(mem), params(p) {}
virtual ~Call() {}
virtual void call_fp() { execute(typename Gens<sizeof...(ATs)>::type()); }
template <int... S>
void execute(Sequence<S...>) { (obj->*fp)(std::get<S>(params)...); }
};
template <typename T, typename R, typename... ATs>
static void *stub(void *vp) {
Call<T, R, ATs...> *call = static_cast<Call<T, R, ATs...> *>(vp);
call->call_fp();
delete call;
return nullptr;
}
// User calls this function
template <typename T, typename R, typename... ATs>
pthread_t pthread_var_arg(T *obj, R (T::*mem)(ATs...), ATs... args) {
std::tuple<ATs...> params = std::make_tuple(args...);
Call<T, R, ATs...> *call_arg_p = new Call<T, R, ATs...>(obj, mem, params);
pthread_t tid = 0;
int ec = pthread_create(&tid, nullptr, stub<T, R, ATs...>, call_arg_p);
assert(ec == 0);
return tid;
}
}
#endif