Go to the documentation of this file.00001
00008
00009
00010
00011
00012 #include <ecl/config/ecl.hpp>
00013 #if defined(ECL_IS_POSIX)
00014
00015
00016
00017
00018
00019 #include <iostream>
00020 #include "../../include/ecl/threads/thread_pos.hpp"
00021 #include <sys/resource.h>
00022
00023
00024
00025
00026
00027 namespace ecl {
00028
00029
00030
00031
00032
00033 Thread::Thread(VoidFunction function, const Priority &priority, const long &stack_size) ecl_debug_throw_decl(StandardException) :
00034 thread_task(NULL),
00035 has_started(false),
00036 join_requested(false)
00037 {
00038 start(function, priority, stack_size);
00039 }
00040
00041 Error Thread::start(VoidFunction function, const Priority &priority, const long &stack_size) ecl_debug_throw_decl(StandardException)
00042 {
00043 if ( has_started ) {
00044 ecl_debug_throw(StandardException(LOC,BusyError,"The thread has already been started."));
00045 return Error(BusyError);
00046 } else {
00047 has_started = true;
00048 }
00049 initialise(stack_size);
00050 NullaryFreeFunction<void> nullary_function_object = generateFunctionObject(function);
00051 thread_task = new threads::ThreadTask< NullaryFreeFunction<void> >(nullary_function_object, priority);
00052 int result = pthread_create(&(this->thread_handle), &(this->attrs), threads::ThreadTask< NullaryFreeFunction<void> >::EntryPoint, thread_task);
00053 pthread_attr_destroy(&attrs);
00054 if ( result != 0 ) {
00055 delete thread_task;
00056 thread_task = NULL;
00057 ecl_debug_throw(threads::throwPthreadCreateException(LOC,result));
00058 return threads::handlePthreadCreateError(result);
00059 }
00060 return Error(NoError);
00061 }
00062
00063 Thread::~Thread() {
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 if ( has_started && !join_requested ) {
00077 pthread_detach(thread_handle);
00078 }
00079 }
00080 void Thread::cancel() ecl_debug_throw_decl(StandardException) {
00081 int result = pthread_cancel(thread_handle);
00082
00083
00084
00085 if ( thread_task != NULL ) {
00086 delete thread_task;
00087 thread_task = NULL;
00088 }
00089 if ( result != 0 ) {
00090 ecl_debug_throw(threads::throwPthreadJoinException(LOC,result));
00091 }
00092 }
00093
00094 void Thread::join() ecl_debug_throw_decl(StandardException) {
00095 join_requested = true;
00096 if( thread_task != NULL ) {
00097 int result = pthread_join( thread_handle, 0 );
00098 ecl_assert_throw( result == 0, threads::throwPthreadJoinException(LOC,result));
00099 }
00100 }
00101
00102 void Thread::initialise(const long &stack_size) ecl_assert_throw_decl(StandardException) {
00103
00104 pthread_attr_init( &attrs );
00105
00106
00107
00108 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
00109
00110 pthread_attr_setinheritsched(&attrs,PTHREAD_INHERIT_SCHED);
00111
00112
00113
00114
00115
00116
00117
00118
00119 pthread_attr_setdetachstate(&attrs,PTHREAD_CREATE_JOINABLE);
00120
00121
00122
00123
00124 if ( stack_size != DefaultStackSize ) {
00125 int result = pthread_attr_setstacksize(&attrs,stack_size);
00126 ecl_assert_throw( result == 0, StandardException(LOC,ConfigurationError,"Specified stack size was less than PTHREAD_STACK_MIN or wasn't a multiple of the page size."));
00127 }
00128 }
00129
00130 };
00131
00132 #endif