00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00022
00023 #include "Thread.h"
00024
00025 #include <icl_core/os_lxrt.h>
00026 #include <icl_core/os_string.h>
00027 #include <icl_core/os_time.h>
00028
00029 #include "Common.h"
00030 #include "Logging.h"
00031
00032 #if defined _SYSTEM_LXRT_
00033 # include "ThreadImplLxrt.h"
00034 #endif
00035
00036 #if defined _SYSTEM_POSIX_
00037 # include "ThreadImplPosix.h"
00038 #elif defined _SYSTEM_WIN32_
00039 # include "ThreadImplWin32.h"
00040 #else
00041 # error "No implementation specified for System dependent components"
00042 #endif
00043
00044 using icl_core::logging::endl;
00045
00046 namespace icl_core {
00047 namespace thread {
00048
00049 Thread::Thread(const icl_core::String& description, ThreadPriority priority)
00050 : m_execute(false),
00051 m_finished(true),
00052 m_joined(true),
00053 m_starting(false),
00054 m_thread_info(description + ", 0"),
00055 m_priority(priority),
00056 m_impl(NULL)
00057 {
00058 #if defined _SYSTEM_LXRT_
00059
00060
00061
00062
00063
00064
00065 if (icl_core::os::isLxrtAvailable())
00066 {
00067 m_impl = new ThreadImplLxrt(this, description, priority);
00068 }
00069 else
00070 {
00071 m_impl = new ThreadImplPosix(this, description, priority);
00072 }
00073
00074 #elif defined _SYSTEM_POSIX_
00075 m_impl = new ThreadImplPosix(this, description, priority);
00076
00077 #elif defined _SYSTEM_WIN32_
00078 m_impl = new ThreadImplWin32(this, description, priority);
00079
00080 #endif
00081 }
00082
00083 Thread::~Thread()
00084 {
00085 if (!m_joined)
00086 {
00087 stop();
00088 join();
00089 }
00090
00091 delete m_impl;
00092 m_impl = NULL;
00093 }
00094
00095 void Thread::cancel()
00096 {
00097 LOGGING_TRACE_CO(IclCoreThread, Thread, threadInfo(), "Begin." << endl);
00098 waitStarted();
00099 if (running())
00100 {
00101 LOGGING_DEBUG_CO(IclCoreThread, Thread, threadInfo(), "Still running." << endl);
00102 m_execute = false;
00103 m_impl->cancel();
00104 m_finished = true;
00105 }
00106 LOGGING_DEBUG_CO(IclCoreThread, Thread, threadInfo(), "Done." << endl);
00107 }
00108
00109 bool Thread::checkHardRealtime()
00110 {
00111 #ifdef _SYSTEM_LXRT_
00112 if (threadSelf() && os::isThisHRT() && !isHardRealtime() && m_priority < 0)
00113 {
00114 return setHardRealtime(true);
00115 }
00116 else
00117 #endif
00118 {
00119 return false;
00120 }
00121 }
00122
00123 icl_core::String Thread::getDescription() const
00124 {
00125 return m_impl->getDescription();
00126 }
00127
00128 bool Thread::isHardRealtime() const
00129 {
00130 return m_impl->isHardRealtime();
00131 }
00132
00133 bool Thread::executesHardRealtime() const
00134 {
00135 return m_impl->executesHardRealtime();
00136 }
00137
00138 void Thread::join()
00139 {
00140 if (running())
00141 {
00142 m_impl->join();
00143 }
00144
00145 m_joined = true;
00146 }
00147
00148 icl_core::ThreadPriority Thread::priority() const
00149 {
00150 return m_impl->priority();
00151 }
00152
00153 void Thread::setDescription(const icl_core::String& description)
00154 {
00155 m_impl->setDescription(description);
00156 }
00157
00158 bool Thread::setHardRealtime(bool hard_realtime)
00159 {
00160 return m_impl->setHardRealtime(hard_realtime);
00161 }
00162
00163 bool Thread::setPriority(icl_core::ThreadPriority priority)
00164 {
00165 if (m_impl->setPriority(priority))
00166 {
00167 m_priority = priority;
00168 return true;
00169 }
00170 else
00171 {
00172 return false;
00173 }
00174 }
00175
00176 bool Thread::start()
00177 {
00178
00179 if (m_starting || running())
00180 {
00181 waitStarted();
00182
00183 return running();
00184 }
00185
00186 m_starting = true;
00187 m_finished = false;
00188
00189 if (!m_joined)
00190 {
00191 join();
00192 }
00193
00194 m_joined = false;
00195
00196 if (!m_impl->start())
00197 {
00198 m_finished = true;
00199 m_starting = false;
00200 m_joined = true;
00201
00202 return false;
00203 }
00204 else
00205 {
00206 waitStarted();
00207
00208 return true;
00209 }
00210 }
00211
00212 icl_core::ThreadId Thread::threadId() const
00213 {
00214 return m_impl->threadId();
00215 }
00216
00217 void Thread::runThread()
00218 {
00219 char buffer[1024];
00220 #if defined(_SYSTEM_WIN32_)
00221 icl_core::os::snprintf(buffer, 1023, "%s, %lu", getDescription().c_str(), threadId());
00222 #elif defined(_SYSTEM_DARWIN_)
00223 icl_core::os::snprintf(buffer, 1023, "%s, %p", getDescription().c_str(), threadId().m_thread_id);
00224 #else
00225 icl_core::os::snprintf(buffer, 1023, "%s, %lu", getDescription().c_str(), threadId().m_thread_id);
00226 #endif
00227 m_thread_info = buffer;
00228
00229 LOGGING_TRACE_CO(IclCoreThread, Thread, threadInfo(), "Begin." << endl);
00230
00231 m_thread_mutex.lock();
00232 m_execute = true;
00233 m_starting = false;
00234 m_finished = false;
00235
00236
00237
00238 makePeriodic();
00239
00240
00241 run();
00242
00243 m_execute = false;
00244 m_thread_mutex.unlock();
00245 m_finished = true;
00246
00247 LOGGING_TRACE_CO(IclCoreThread, Thread, threadInfo(), "Done." << endl);
00248 }
00249
00250 bool Thread::wait()
00251 {
00252 return wait(icl_core::TimeStamp::maxTime());
00253 }
00254
00255 bool Thread::wait(const icl_core::TimeStamp& until)
00256 {
00257 bool success = false;
00258
00259 if (m_joined)
00260 {
00261 return true;
00262 }
00263
00264 waitStarted();
00265
00266 if (m_finished)
00267 {
00268 success = true;
00269 }
00270 else if ((until == icl_core::TimeStamp::maxTime() && m_thread_mutex.lock())
00271 || m_thread_mutex.lock(until))
00272 {
00273 m_thread_mutex.unlock();
00274 }
00275 else if (icl_core::TimeStamp::now() < until)
00276 {
00277 LOGGING_ERROR_CO(IclCoreThread, Thread, threadInfo(),
00278 "Thread is running and we should still wait, but LockMutex() returned unexpected."
00279 "The wait function will now block further until the thread is really finished."
00280 "But consider that your implementation could have a failure in locking ..." << endl);
00281
00282 while (icl_core::TimeStamp::now() < until && !m_finished)
00283 {
00284 os::sleep(1);
00285 }
00286 }
00287
00288 if (m_finished)
00289 {
00290 success = true;
00291 }
00292
00293 if (success)
00294 {
00295 join();
00296 return true;
00297 }
00298 else
00299 {
00300 LOGGING_ERROR_CO(IclCoreThread, Thread, threadInfo(), "Wait not succesful." << endl);
00301 return false;
00302 }
00303 }
00304
00305 bool Thread::wait(const icl_core::TimeSpan& timeout)
00306 {
00307 return wait(impl::getAbsoluteTimeout(timeout));
00308 }
00309
00311 #ifdef _IC_BUILDER_DEPRECATED_STYLE_
00312
00321 void Thread::Cancel()
00322 {
00323 cancel();
00324 }
00325
00329 bool Thread::CheckHardRealtime()
00330 {
00331 return checkHardRealtime();
00332 }
00333
00337 icl_core::String Thread::Description() const
00338 {
00339 return getDescription();
00340 }
00341
00346 bool Thread::Execute() const
00347 {
00348 return execute();
00349 }
00350
00354 bool Thread::IsHardRealtime() const
00355 {
00356 return isHardRealtime();
00357 }
00358
00363 bool Thread::ExecutesHardRealtime() const
00364 {
00365 return executesHardRealtime();
00366 }
00367
00371 void Thread::Join()
00372 {
00373 join();
00374 }
00375
00379 icl_core::ThreadPriority Thread::Priority() const
00380 {
00381 return priority();
00382 }
00383
00387 bool Thread::Running() const
00388 {
00389 return running();
00390 }
00391
00395 void Thread::SetDescription(const icl_core::String& description)
00396 {
00397 setDescription(description);
00398 }
00399
00403 bool Thread::SetHardRealtime(bool hard_realtime)
00404 {
00405 return setHardRealtime(hard_realtime);
00406 }
00407
00411 bool Thread::SetPriority(icl_core::ThreadPriority priority)
00412 {
00413 return setPriority(priority);
00414 }
00415
00419 bool Thread::Start()
00420 {
00421 return start();
00422 }
00423
00427 void Thread::Stop()
00428 {
00429 stop();
00430 }
00431
00435 icl_core::ThreadId Thread::ThreadId() const
00436 {
00437 return threadId();
00438 }
00439
00444 const char *Thread::ThreadInfo() const
00445 {
00446 return threadInfo();
00447 }
00448
00453 bool Thread::ThreadSelf() const
00454 {
00455 return threadSelf();
00456 }
00457
00461 bool Thread::Wait()
00462 {
00463 return wait();
00464 }
00465
00470 bool Thread::Wait(const icl_core::TimeStamp& timeout)
00471 {
00472 return wait(timeout);
00473 }
00474
00479 bool Thread::Wait(const icl_core::TimeSpan& timeout)
00480 {
00481 return wait(timeout);
00482 }
00483
00487 icl_core::ThreadId Thread::SelfId()
00488 {
00489 return selfId();
00490 }
00491
00492 #endif
00493
00494
00495 void Thread::waitStarted() const
00496 {
00497 while (m_starting)
00498 {
00499
00500 icl_core::os::usleep(1);
00501 }
00502 }
00503
00504 void Thread::makePeriodic()
00505 {
00506 }
00507
00509 #ifdef _IC_BUILDER_DEPRECATED_STYLE_
00510
00514 void Thread::RunThread()
00515 {
00516 runThread();
00517 }
00518
00522 void Thread::WaitStarted() const
00523 {
00524 waitStarted();
00525 }
00526
00527 #endif
00528
00529
00530 }
00531 }