namespace thread {
/**
\brief Thread class for running member functions in a separate thread.
Example:
\code{.cpp}
struct trooper {
void figth(int num) {
std::cerr << "fighting: " << num << '\n';
}
};
trooper tr1;
trooper tr2;
thread para_trooper1(&trooper::fight, &tr1, 1);
thread para_trooper2(&trooper::fight, &tr2, 2);
\endcode
*/
struct thread
{
/**
\brief Creates a thread for a member function with no parameters.
\param f Member function with signature T::*()
\param t Object of type T where f can be called
*/
template<typename F, typename T>
thread(F f, T t) : joinable_(false), id_(0)
{
thread_helper_a0<F, T>* ph = new thread_helper_a0<F, T>(f, t);
int const res = pthread_create(&id_, 0, &thread_helper_a0<F, T>::call, ph);
if (res)
{
delete ph;
throw std::runtime_error("thread creation failed");
}
joinable_ = true;
}
/**
\brief Creates a thread for a member function with one parameters.
\param f Member function with signature T::*(A)
\param t Object of type T where f can be called
\param a Parameter for thread function f
*/
template<typename F, typename T, typename A>
thread(F f, T t, A a) : joinable_(false), id_(0)
{
thread_helper_a1<F, T, A>* ph = new thread_helper_a1<F, T, A>(f, t, a);
int const res = pthread_create(&id_, 0, &thread_helper_a1<F, T, A>::call, ph);
if (res)
{
delete ph;
throw std::runtime_error("thread creation failed");
}
joinable_ = true;
}
/**
\brief Creates a thread for a member function with two parameters.
\param f Member function with signature T::*(A)
\param t Object of type T where f can be called
\param a first parameter for thread function f
\param b second parameter for thread function f
*/
template<typename F, typename T, typename A, typename B>
thread(F f, T t, A a, B b) : joinable_(false), id_(0)
{
thread_helper_a2<F, T, A, B>* ph = new thread_helper_a2<F, T, A, B>(f, t, a, b);
int const res = pthread_create(&id_, 0, &thread_helper_a2<F, T, A, B>::call, ph);
if (res)
{
delete ph;
throw std::runtime_error("thread creation failed");
}
joinable_ = true;
}
/**
\brief Join with thread if thread is joinable otherwise throws an
exception of type std::runtime_error.
*/
void join()
{
if (!joinable_)
throw std::logic_error("thread not joinable");
int const res = pthread_join(id_, 0);
if (res)
throw std::runtime_error("thread joining failed");
}
/**
\brief Detaches thread if thread is joinable otherwise throws an
exception of type std::runtime_exception.
*/
void detach()
{
if (!joinable_)
throw std::logic_error("thread not detachable");
int const res = pthread_detach(id_);
if (res)
throw std::runtime_error("thread detaching failed");
}
~thread()
{
}
private:
template<typename F, typename T>
struct thread_helper_a0
{
thread_helper_a0(F f, T t) : f(f), t(t) {}
static void* call(void* data)
{
thread_helper_a0* th = (thread_helper_a0*)data;
F f = th->f;
T t = th->t;
delete th;
(t->*f)();
return 0;
}
F f;
T t;
};
template<typename F, typename T, typename A>
struct thread_helper_a1
{
thread_helper_a1(F f, T t, A a) : f(f), t(t), a(a) {}
static void* call(void* data)
{
thread_helper_a1* th = (thread_helper_a1*)data;
F f = th->f;
T t = th->t;
A a = th->a;
delete th;
(t->*f)(a);
return 0;
}
F f;
T t;
A a;
};
template<typename F, typename T, typename A, typename B>
struct thread_helper_a2
{
thread_helper_a2(F f, T t, A a, B b) : f(f), t(t), a(a), b(b) {}
static void* call(void* data)
{
thread_helper_a2* th = (thread_helper_a2*)data;
F f = th->f;
T t = th->t;
A a = th->a;
B b = th->b;
delete th;
(t->*f)(a,b);
return 0;
}
F f;
T t;
A a;
B b;
};
thread();
thread(thread const&);
thread const& operator=(thread const&);
bool joinable_;
pthread_t id_;
};
}
bmFtZXNwYWNlIHRocmVhZCB7CgovKioKICAgIFxicmllZiBUaHJlYWQgY2xhc3MgZm9yIHJ1bm5pbmcgbWVtYmVyIGZ1bmN0aW9ucyBpbiBhIHNlcGFyYXRlIHRocmVhZC4KCiAgICBFeGFtcGxlOgogICAgXGNvZGV7LmNwcH0KICAgIHN0cnVjdCB0cm9vcGVyIHsKICAgICAgICB2b2lkIGZpZ3RoKGludCBudW0pIHsKICAgICAgICAgICAgc3RkOjpjZXJyIDw8ICJmaWdodGluZzogIiA8PCBudW0gPDwgJ1xuJzsKICAgICAgICB9CiAgICB9OwoKICAgIHRyb29wZXIgdHIxOwogICAgdHJvb3BlciB0cjI7CiAgICB0aHJlYWQgcGFyYV90cm9vcGVyMSgmdHJvb3Blcjo6ZmlnaHQsICZ0cjEsIDEpOwogICAgdGhyZWFkIHBhcmFfdHJvb3BlcjIoJnRyb29wZXI6OmZpZ2h0LCAmdHIyLCAyKTsKICAgIFxlbmRjb2RlCgoqLwpzdHJ1Y3QgdGhyZWFkCnsKICAgIC8qKgogICAgICAgIFxicmllZiBDcmVhdGVzIGEgdGhyZWFkIGZvciBhIG1lbWJlciBmdW5jdGlvbiB3aXRoIG5vIHBhcmFtZXRlcnMuCgogICAgICAgIFxwYXJhbSBmIE1lbWJlciBmdW5jdGlvbiB3aXRoIHNpZ25hdHVyZSBUOjoqKCkKICAgICAgICBccGFyYW0gdCBPYmplY3Qgb2YgdHlwZSBUIHdoZXJlIGYgY2FuIGJlIGNhbGxlZAogICAgKi8KICAgIHRlbXBsYXRlPHR5cGVuYW1lIEYsIHR5cGVuYW1lIFQ+CiAgICB0aHJlYWQoRiBmLCBUIHQpIDogam9pbmFibGVfKGZhbHNlKSwgaWRfKDApCiAgICB7CiAgICAgICAgdGhyZWFkX2hlbHBlcl9hMDxGLCBUPiogcGggPSBuZXcgdGhyZWFkX2hlbHBlcl9hMDxGLCBUPihmLCB0KTsKICAgICAgICBpbnQgY29uc3QgcmVzID0gcHRocmVhZF9jcmVhdGUoJmlkXywgMCwgJnRocmVhZF9oZWxwZXJfYTA8RiwgVD46OmNhbGwsIHBoKTsKICAgICAgICBpZiAocmVzKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIHBoOwogICAgICAgICAgICB0aHJvdyBzdGQ6OnJ1bnRpbWVfZXJyb3IoInRocmVhZCBjcmVhdGlvbiBmYWlsZWQiKTsKICAgICAgICB9CiAgICAgICAgam9pbmFibGVfID0gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAgICBcYnJpZWYgQ3JlYXRlcyBhIHRocmVhZCBmb3IgYSBtZW1iZXIgZnVuY3Rpb24gd2l0aCBvbmUgcGFyYW1ldGVycy4KCiAgICAgICAgXHBhcmFtIGYgTWVtYmVyIGZ1bmN0aW9uIHdpdGggc2lnbmF0dXJlIFQ6OiooQSkKICAgICAgICBccGFyYW0gdCBPYmplY3Qgb2YgdHlwZSBUIHdoZXJlIGYgY2FuIGJlIGNhbGxlZAogICAgICAgIFxwYXJhbSBhIFBhcmFtZXRlciBmb3IgdGhyZWFkIGZ1bmN0aW9uIGYKICAgICovCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBGLCB0eXBlbmFtZSBULCB0eXBlbmFtZSBBPgogICAgdGhyZWFkKEYgZiwgVCB0LCBBIGEpIDogam9pbmFibGVfKGZhbHNlKSwgaWRfKDApCiAgICB7CiAgICAgICAgdGhyZWFkX2hlbHBlcl9hMTxGLCBULCBBPiogcGggPSBuZXcgdGhyZWFkX2hlbHBlcl9hMTxGLCBULCBBPihmLCB0LCBhKTsKICAgICAgICBpbnQgY29uc3QgcmVzID0gcHRocmVhZF9jcmVhdGUoJmlkXywgMCwgJnRocmVhZF9oZWxwZXJfYTE8RiwgVCwgQT46OmNhbGwsIHBoKTsKICAgICAgICBpZiAocmVzKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIHBoOwogICAgICAgICAgICB0aHJvdyBzdGQ6OnJ1bnRpbWVfZXJyb3IoInRocmVhZCBjcmVhdGlvbiBmYWlsZWQiKTsKICAgICAgICB9CiAgICAgICAgam9pbmFibGVfID0gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAgICBcYnJpZWYgQ3JlYXRlcyBhIHRocmVhZCBmb3IgYSBtZW1iZXIgZnVuY3Rpb24gd2l0aCB0d28gcGFyYW1ldGVycy4KCiAgICAgICAgXHBhcmFtIGYgTWVtYmVyIGZ1bmN0aW9uIHdpdGggc2lnbmF0dXJlIFQ6OiooQSkKICAgICAgICBccGFyYW0gdCBPYmplY3Qgb2YgdHlwZSBUIHdoZXJlIGYgY2FuIGJlIGNhbGxlZAogICAgICAgIFxwYXJhbSBhIGZpcnN0IHBhcmFtZXRlciBmb3IgdGhyZWFkIGZ1bmN0aW9uIGYKICAgICAgICBccGFyYW0gYiBzZWNvbmQgcGFyYW1ldGVyIGZvciB0aHJlYWQgZnVuY3Rpb24gZgogICAgKi8KICAgIHRlbXBsYXRlPHR5cGVuYW1lIEYsIHR5cGVuYW1lIFQsIHR5cGVuYW1lIEEsIHR5cGVuYW1lIEI+CiAgICB0aHJlYWQoRiBmLCBUIHQsIEEgYSwgQiBiKSA6IGpvaW5hYmxlXyhmYWxzZSksIGlkXygwKQogICAgewogICAgICAgIHRocmVhZF9oZWxwZXJfYTI8RiwgVCwgQSwgQj4qIHBoID0gbmV3IHRocmVhZF9oZWxwZXJfYTI8RiwgVCwgQSwgQj4oZiwgdCwgYSwgYik7CiAgICAgICAgaW50IGNvbnN0IHJlcyA9IHB0aHJlYWRfY3JlYXRlKCZpZF8sIDAsICZ0aHJlYWRfaGVscGVyX2EyPEYsIFQsIEEsIEI+OjpjYWxsLCBwaCk7CiAgICAgICAgaWYgKHJlcykKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBwaDsKICAgICAgICAgICAgdGhyb3cgc3RkOjpydW50aW1lX2Vycm9yKCJ0aHJlYWQgY3JlYXRpb24gZmFpbGVkIik7CiAgICAgICAgfQogICAgICAgIGpvaW5hYmxlXyA9IHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgICAgXGJyaWVmIEpvaW4gd2l0aCB0aHJlYWQgaWYgdGhyZWFkIGlzIGpvaW5hYmxlIG90aGVyd2lzZSB0aHJvd3MgYW4KICAgICAgICBleGNlcHRpb24gb2YgdHlwZSBzdGQ6OnJ1bnRpbWVfZXJyb3IuCiAgICAqLwogICAgdm9pZCBqb2luKCkKICAgIHsKICAgICAgICBpZiAoIWpvaW5hYmxlXykKICAgICAgICAgICAgdGhyb3cgc3RkOjpsb2dpY19lcnJvcigidGhyZWFkIG5vdCBqb2luYWJsZSIpOwogICAgICAgIGludCBjb25zdCByZXMgPSBwdGhyZWFkX2pvaW4oaWRfLCAwKTsKICAgICAgICBpZiAocmVzKQogICAgICAgICAgICB0aHJvdyBzdGQ6OnJ1bnRpbWVfZXJyb3IoInRocmVhZCBqb2luaW5nIGZhaWxlZCIpOwogICAgfQoKICAgIC8qKgogICAgICAgIFxicmllZiBEZXRhY2hlcyB0aHJlYWQgaWYgdGhyZWFkIGlzIGpvaW5hYmxlIG90aGVyd2lzZSB0aHJvd3MgYW4KICAgICAgICBleGNlcHRpb24gb2YgdHlwZSBzdGQ6OnJ1bnRpbWVfZXhjZXB0aW9uLgogICAgKi8KICAgIHZvaWQgZGV0YWNoKCkKICAgIHsKICAgICAgICBpZiAoIWpvaW5hYmxlXykKICAgICAgICAgICAgdGhyb3cgc3RkOjpsb2dpY19lcnJvcigidGhyZWFkIG5vdCBkZXRhY2hhYmxlIik7CiAgICAgICAgaW50IGNvbnN0IHJlcyA9IHB0aHJlYWRfZGV0YWNoKGlkXyk7CiAgICAgICAgaWYgKHJlcykKICAgICAgICAgICAgdGhyb3cgc3RkOjpydW50aW1lX2Vycm9yKCJ0aHJlYWQgZGV0YWNoaW5nIGZhaWxlZCIpOwogICAgfQoKICAgIH50aHJlYWQoKQogICAgewogICAgfQoKcHJpdmF0ZToKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEYsIHR5cGVuYW1lIFQ+CiAgICBzdHJ1Y3QgdGhyZWFkX2hlbHBlcl9hMAogICAgewogICAgICAgIHRocmVhZF9oZWxwZXJfYTAoRiBmLCBUIHQpIDogZihmKSwgdCh0KSB7fQoKICAgICAgICBzdGF0aWMgdm9pZCogY2FsbCh2b2lkKiBkYXRhKQogICAgICAgIHsKICAgICAgICAgICAgdGhyZWFkX2hlbHBlcl9hMCogdGggPSAodGhyZWFkX2hlbHBlcl9hMCopZGF0YTsKICAgICAgICAgICAgRiBmID0gdGgtPmY7CiAgICAgICAgICAgIFQgdCA9IHRoLT50OwogICAgICAgICAgICBkZWxldGUgdGg7CiAgICAgICAgICAgICh0LT4qZikoKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICBGIGY7CiAgICAgICAgVCB0OwogICAgfTsKCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBGLCB0eXBlbmFtZSBULCB0eXBlbmFtZSBBPgogICAgc3RydWN0IHRocmVhZF9oZWxwZXJfYTEKICAgIHsKICAgICAgICB0aHJlYWRfaGVscGVyX2ExKEYgZiwgVCB0LCBBIGEpIDogZihmKSwgdCh0KSwgYShhKSB7fQoKICAgICAgICBzdGF0aWMgdm9pZCogY2FsbCh2b2lkKiBkYXRhKQogICAgICAgIHsKICAgICAgICAgICAgdGhyZWFkX2hlbHBlcl9hMSogdGggPSAodGhyZWFkX2hlbHBlcl9hMSopZGF0YTsKICAgICAgICAgICAgRiBmID0gdGgtPmY7CiAgICAgICAgICAgIFQgdCA9IHRoLT50OwogICAgICAgICAgICBBIGEgPSB0aC0+YTsKICAgICAgICAgICAgZGVsZXRlIHRoOwogICAgICAgICAgICAodC0+KmYpKGEpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIEYgZjsKICAgICAgICBUIHQ7CiAgICAgICAgQSBhOwogICAgfTsKCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBGLCB0eXBlbmFtZSBULCB0eXBlbmFtZSBBLCB0eXBlbmFtZSBCPgogICAgc3RydWN0IHRocmVhZF9oZWxwZXJfYTIKICAgIHsKICAgICAgICB0aHJlYWRfaGVscGVyX2EyKEYgZiwgVCB0LCBBIGEsIEIgYikgOiBmKGYpLCB0KHQpLCBhKGEpLCBiKGIpIHt9CgogICAgICAgIHN0YXRpYyB2b2lkKiBjYWxsKHZvaWQqIGRhdGEpCiAgICAgICAgewogICAgICAgICAgICB0aHJlYWRfaGVscGVyX2EyKiB0aCA9ICh0aHJlYWRfaGVscGVyX2EyKilkYXRhOwogICAgICAgICAgICBGIGYgPSB0aC0+ZjsKICAgICAgICAgICAgVCB0ID0gdGgtPnQ7CiAgICAgICAgICAgIEEgYSA9IHRoLT5hOwogICAgICAgICAgICBCIGIgPSB0aC0+YjsKICAgICAgICAgICAgZGVsZXRlIHRoOwogICAgICAgICAgICAodC0+KmYpKGEsYik7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgRiBmOwogICAgICAgIFQgdDsKICAgICAgICBBIGE7CiAgICAgICAgQiBiOwogICAgfTsKCiAgICB0aHJlYWQoKTsKICAgIHRocmVhZCh0aHJlYWQgY29uc3QmKTsKICAgIHRocmVhZCBjb25zdCYgb3BlcmF0b3I9KHRocmVhZCBjb25zdCYpOwoKICAgIGJvb2wgam9pbmFibGVfOwogICAgcHRocmVhZF90IGlkXzsKfTsKCgoKfQ==