thread_win.cpp
Go to the documentation of this file.
00001 
00008 /*****************************************************************************
00009 ** Platform Check
00010 *****************************************************************************/
00011 
00012 #include <ecl/config/ecl.hpp>
00013 #if defined(ECL_IS_WIN32)
00014 
00015 /*****************************************************************************
00016 ** Includes
00017 *****************************************************************************/
00018 
00019 #include <iostream>
00020 #include "../../include/ecl/threads/thread_win.hpp"
00021 
00022 /*****************************************************************************
00023 ** Namespaces
00024 *****************************************************************************/
00025 
00026 namespace ecl {
00027 
00028 /*****************************************************************************
00029 * Thread Class Methods
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         // stack_size is ignored
00044 
00045         if ( has_started ) {
00046                 ecl_debug_throw(StandardException(LOC,BusyError,"The thread has already been started."));
00047                 return Error(BusyError); // if in release mode, gracefully fall back to return values.
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                                 // unsafe termination.
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         // stack_size is ignored
00133 }
00134 
00135 }; // namespace ecl
00136 
00137 #endif /* ECL_IS_WIN32 */


ecl_threads
Author(s): Daniel Stonier
autogenerated on Thu Jun 6 2019 21:18:01