Thread.cpp
Go to the documentation of this file.
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 2014 FZI Forschungszentrum Informatik, Karlsruhe, Germany
00012 //
00013 // -- END LICENSE BLOCK ------------------------------------------------
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   // Only create an LXRT implementation if the LXRT runtime system
00060   // is really available. Otherwise create an ACE or POSIX implementation,
00061   // depending on the system configuration.
00062   // Remark: This allows us to compile programs with LXRT support but run
00063   // them on systems on which no LXRT is installed and to disable LXRT support
00064   // at program startup on systems with installed LXRT!
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   // Don't do anything if the thread is already starting or running.
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   // If this is actually a periodic thread, this call makes it periodic.
00237   // It this is a "normal" thread, this call does nothing.
00238   makePeriodic();
00239 
00240   // Call the run loop.
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     // Sleep for 1 microsecond.
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 }


schunk_svh_driver
Author(s): Georg Heppner
autogenerated on Fri Aug 28 2015 12:59:19