00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 00002 00003 // -- BEGIN LICENSE BLOCK ---------------------------------------------- 00004 // This file is part of FZIs ic_workspace. 00005 // 00006 // This program is free software licensed under the LGPL 00007 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3). 00008 // You can find a copy of this license in LICENSE folder in the top 00009 // directory of the source code. 00010 // 00011 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany 00012 // 00013 // -- END LICENSE BLOCK ------------------------------------------------ 00014 00015 //---------------------------------------------------------------------- 00022 //---------------------------------------------------------------------- 00023 #include "Thread.h" 00024 00025 #include <icl_core/os_time.h> 00026 00027 #if defined _SYSTEM_LXRT_ 00028 # include "ThreadImplLxrt.h" 00029 #endif 00030 00031 #if defined _SYSTEM_POSIX_ 00032 # include "ThreadImplPosix.h" 00033 #elif defined _SYSTEM_WIN32_ 00034 # include "ThreadImplWin32.h" 00035 #else 00036 # error "No thread implementation defined for this platform." 00037 #endif 00038 00039 namespace icl_core { 00040 namespace logging { 00041 00042 Thread::Thread(icl_core::ThreadPriority priority) 00043 : m_execute(false), 00044 m_finished(true), 00045 m_joined(true), 00046 m_starting(false), 00047 m_impl(0) 00048 { 00049 #if defined _SYSTEM_LXRT_ 00050 // Only create an LXRT implementation if the LXRT runtime system 00051 // is really available. Otherwise create an ACE or POSIX implementation, 00052 // depending on the system configuration. 00053 // Remark: This allows us to compile programs with LXRT support but run 00054 // them on systems on which no LXRT is installed and to disable LXRT support 00055 // at program startup on systems with installed LXRT! 00056 if (icl_core::os::isThisLxrtTask()) 00057 { 00058 m_impl = new ThreadImplLxrt(this, priority); 00059 } 00060 else 00061 { 00062 m_impl = new ThreadImplPosix(this, priority); 00063 } 00064 00065 #elif defined _SYSTEM_POSIX_ 00066 m_impl = new ThreadImplPosix(this, priority); 00067 00068 #elif defined _SYSTEM_WIN32_ 00069 m_impl = new ThreadImplWin32(this, priority); 00070 00071 #endif 00072 } 00073 00074 Thread::~Thread() 00075 { 00076 if (!m_joined) 00077 { 00078 stop(); 00079 join(); 00080 } 00081 delete m_impl; 00082 } 00083 00084 void Thread::join() 00085 { 00086 if (running()) 00087 { 00088 m_impl->join(); 00089 } 00090 00091 m_joined = true; 00092 } 00093 00094 bool Thread::start() 00095 { 00096 // Don't do anything if the thread is already starting or running. 00097 if (m_starting || running()) 00098 { 00099 waitStarted(); 00100 00101 return running(); 00102 } 00103 00104 m_starting = true; 00105 m_finished = false; 00106 00107 if (!m_joined) 00108 { 00109 join(); 00110 } 00111 00112 m_joined = false; 00113 00114 if (!m_impl->start()) 00115 { 00116 m_finished = true; 00117 m_starting = false; 00118 m_joined = true; 00119 00120 return false; 00121 } 00122 else 00123 { 00124 waitStarted(); 00125 00126 return true; 00127 } 00128 } 00129 00130 void Thread::runThread() 00131 { 00132 m_execute = true; 00133 m_starting = false; 00134 m_finished = false; 00135 00136 run(); 00137 00138 m_execute = false; 00139 m_finished = true; 00140 } 00141 00142 void Thread::waitStarted() const 00143 { 00144 while (m_starting) 00145 { 00146 // Sleep for 1 microsecond. 00147 icl_core::os::usleep(1); 00148 } 00149 } 00150 00151 } 00152 }