Go to the documentation of this file.00001
00008
00009
00010
00011
00012 #include <ecl/config/ecl.hpp>
00013 #if defined(ECL_IS_WIN32)
00014
00015
00016
00017
00018
00019 #include <iostream>
00020 #include "../../include/ecl/threads/thread_win.hpp"
00021
00022
00023
00024
00025
00026 namespace ecl {
00027
00028
00029
00030
00031
00032 Thread::Thread(VoidFunction function, const Priority &priority, const long &stack_size) ecl_debug_throw_decl(StandardException) :
00033 thread_handle(NULL),
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
00044
00045 if ( has_started ) {
00046 ecl_debug_throw(StandardException(LOC,BusyError,"The thread has already been started."));
00047 return Error(BusyError);
00048 } else {
00049 has_started = true;
00050 }
00051
00052 NullaryFreeFunction<void> nullary_function_object = generateFunctionObject(function);
00053 thread_task = new threads::ThreadTask< NullaryFreeFunction<void> >(nullary_function_object, priority);
00054
00055 DWORD threadid;
00056
00057 thread_handle = CreateThread(NULL,
00058 0,
00059 (LPTHREAD_START_ROUTINE)threads::ThreadTask< NullaryFreeFunction<void> >::EntryPoint,
00060 thread_task,
00061 0,
00062 &threadid);
00063
00064 if (!thread_handle) {
00065 ecl_debug_throw(StandardException(LOC, UnknownError, "Failed to create thread."));
00066 return Error(UnknownError);
00067 }
00068
00069 BOOL bResult = FALSE;
00070
00071 if (priority >= RealTimePriority1) {
00072 bResult = SetThreadPriority(thread_handle, THREAD_PRIORITY_TIME_CRITICAL);
00073 }
00074
00075 switch (priority) {
00076 case CriticalPriority:
00077 bResult = SetThreadPriority(thread_handle, HIGH_PRIORITY_CLASS);
00078 break;
00079 case HighPriority:
00080 bResult = SetThreadPriority(thread_handle, THREAD_PRIORITY_ABOVE_NORMAL);
00081 break;
00082 case LowPriority:
00083 bResult = SetThreadPriority(thread_handle, THREAD_PRIORITY_BELOW_NORMAL);
00084 break;
00085 case BackgroundPriority:
00086 bResult = SetThreadPriority(thread_handle, THREAD_PRIORITY_IDLE);
00087 break;
00088 default:
00089 break;
00090 }
00091
00092 if (!bResult) {
00093 ecl_debug_throw(threads::throwPriorityException(LOC));
00094 }
00095
00096 return Error(NoError);
00097 }
00098
00099 Thread::~Thread() {
00100 cancel();
00101 }
00102
00103 void Thread::cancel() ecl_debug_throw_decl(StandardException) {
00104 if (thread_handle) {
00105 unsigned long exitcode;
00106 if (::GetExitCodeThread(thread_handle, &exitcode)) {
00107 if (exitcode == 0x0103) {
00108
00109 ::TerminateThread(thread_handle, exitcode);
00110 }
00111 }
00112 ::CloseHandle(thread_handle);
00113 thread_handle = NULL;
00114 }
00115 if (thread_task) {
00116 delete thread_task;
00117 thread_task = NULL;
00118 }
00119 has_started = false;
00120 join_requested = false;
00121 }
00122
00123 void Thread::join() ecl_debug_throw_decl(StandardException) {
00124 join_requested = true;
00125
00126 if (thread_handle) {
00127 WaitForSingleObject(thread_handle, INFINITE);
00128 }
00129 }
00130
00131 void Thread::initialise(const long &stack_size) ecl_assert_throw_decl(StandardException) {
00132
00133 }
00134
00135 };
00136
00137 #endif