88
99#include " pthread/thread.hpp"
1010#include < unistd.h>
11+ #include < cstdio>
1112
1213namespace pthread {
1314
@@ -22,21 +23,36 @@ namespace pthread {
2223 }
2324 }
2425
25- int thread::join () {
26- int rc = 0 ;
27-
28- if ( _thread == this_thread::get_id ()){
29- throw pthread_exception (" join failed, join yourself would endup in deadlock." );
30- }
31- if ( _status == thread_status::not_a_thread ){
32- throw pthread_exception (" join failed, this is not a thread." );
33- }
26+ void *thread::join () {
27+ int rc = 0 ;
28+ void *retval = 0 ;
3429
35- if ( (rc = pthread_join (_thread, (void **)&_status)) != 0 ){
36- throw thread_exception (" pthread_join failed." , rc );
30+ #if __cplusplus < 201103L
31+ if ( _thread != NULL ){
32+ #else
33+ if ( _thread != nullptr ){
34+ #endif
35+
36+ if ( _thread == this_thread::get_id ()){
37+ throw pthread_exception (" join failed, join yourself would endup in deadlock." );
38+ }
39+
40+ if ( _status == thread_status::not_a_thread ){
41+ throw pthread_exception (" join failed, this is not a thread." );
42+ }
43+
44+ if ( (rc = pthread_join (_thread, (void **)&retval)) != 0 ){
45+ switch ( rc ) {
46+ case EDEADLK:
47+ throw thread_exception (" EDEADLKpthread_join failed because of deadlock conditions." , rc );
48+ case EINVAL:
49+ throw thread_exception (" EINVEL pthread_join failed not a joinable thread." , rc );
50+ case ESRCH:
51+ break ; // thread has already ended.
52+ }
53+ }
3754 }
38-
39- return rc;
55+ return retval;
4056 }
4157
4258 int thread::cancel () {
@@ -72,7 +88,7 @@ namespace pthread {
7288 }
7389
7490 if ( stack_size > 0 && (rc = pthread_attr_setstacksize (&_attr, stack_size)) != 0 ){
75- throw thread_exception (" pthread_attr_setstacksize failed ." , rc );
91+ throw thread_exception (" bad stacksize, check size passed to thread::thread; thread not started ." , rc );
7692 }
7793
7894 if ((rc = pthread_create (&_thread, &_attr, thread_startup_runnable, (void *) &work)) != 0 ){
@@ -128,7 +144,9 @@ namespace pthread {
128144 }
129145
130146 thread_group::~thread_group (){
147+
131148 while (! _threads.empty ()){
149+
132150#if __cplusplus < 201103L
133151 std::auto_ptr<pthread::abstract_thread> pat (_threads.front ());
134152#else
@@ -137,9 +155,11 @@ namespace pthread {
137155
138156 _threads.pop_front ();
139157
140- if ( _destructor_joins_first ){
158+ if ( _destructor_joins_first && pat-> joinable () ){
141159 try {
142160 pat->join ();
161+ } catch ( pthread_exception &err ){
162+ printf (" thread_group destructor failed to join one thread. %s, (%d) %s.\n " , err.what (), err.pthread_errno (), err.pthread_errmsg ());
143163 } catch ( ... ){};
144164 }
145165 }
@@ -158,7 +178,9 @@ namespace pthread {
158178
159179 void thread_group::join (){
160180 for (auto iterator = _threads.begin (); iterator != _threads.end (); iterator++){
161- (*iterator)->join ();
181+ if ( (*iterator)->joinable () ){
182+ (*iterator)->join ();
183+ }
162184 }
163185 }
164186
0 commit comments