1 2 // vim:sw=2:ai 3 4 /* 5 * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. 6 * Copyright (C) 2011 Kentoku SHIBA 7 * See COPYRIGHT.txt for details. 8 */ 9 10 #ifndef DENA_THREAD_HPP 11 #define DENA_THREAD_HPP 12 13 #include "fatal.hpp" 14 15 namespace dena { 16 17 /* 18 template <typename T> 19 struct thread : private noncopyable { 20 template <typename Ta> thread(const Ta& arg, size_t stack_sz = 256 * 1024) 21 : obj(arg), thr(0), need_join(false), stack_size(stack_sz) { } 22 template <typename Ta0, typename Ta1> thread(const Ta0& a0, 23 volatile Ta1& a1, size_t stack_sz = 256 * 1024) 24 : obj(a0, a1), thr(0), need_join(false), stack_size(stack_sz) { } 25 ~thread() { 26 join(); 27 } 28 void start() { 29 if (!start_nothrow()) { 30 fatal_abort("thread::start"); 31 } 32 } 33 bool start_nothrow() { 34 if (need_join) { 35 return need_join; 36 } 37 void *const arg = this; 38 pthread_attr_t attr; 39 if (pthread_attr_init(&attr) != 0) { 40 fatal_abort("pthread_attr_init"); 41 } 42 if (pthread_attr_setstacksize(&attr, stack_size) != 0) { 43 fatal_abort("pthread_attr_setstacksize"); 44 } 45 const int r = pthread_create(&thr, &attr, thread_main, arg); 46 if (pthread_attr_destroy(&attr) != 0) { 47 fatal_abort("pthread_attr_destroy"); 48 } 49 if (r != 0) { 50 return need_join; 51 } 52 need_join = true; 53 return need_join; 54 } 55 void join() { 56 if (!need_join) { 57 return; 58 } 59 int e = 0; 60 if ((e = pthread_join(thr, 0)) != 0) { 61 fatal_abort("pthread_join"); 62 } 63 need_join = false; 64 } 65 T& operator *() { return obj; } 66 T *operator ->() { return &obj; } 67 private: 68 static void *thread_main(void *arg) { 69 thread *p = static_cast<thread *>(arg); 70 p->obj(); 71 return 0; 72 } 73 private: 74 T obj; 75 pthread_t thr; 76 bool need_join; 77 size_t stack_size; 78 }; 79 */ 80 81 }; 82 83 #endif 84 85