Changeset 8:5a3625dd40e8 in rrlib_thread


Ignore:
Timestamp:
29.04.2013 01:53:54 (6 years ago)
Author:
Max Reichardt <mreichardt@…>
Branch:
default
Phase:
public
Message:

Added TryLock() function(ality) to class tLock. Fixed small issues in thread class.

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • tLock.h

    r1 r8  
    3232 * Lock for all mutex classes in rrlib_thread 
    3333 * 
     34 * (Wraps std::unique_lock for different mutex types. 
     35 *  Additionally enforces correct lock order if #define 
     36 *  RRLIB_THREAD_ENFORCE_LOCK_ORDER is enabled) 
     37 * 
    3438 */ 
    3539//---------------------------------------------------------------------- 
     
    7377// Class declaration 
    7478//---------------------------------------------------------------------- 
    75 //! Lock 
     79//! Unique Lock 
    7680/*! 
    7781 * Lock for all mutex classes in rrlib_thread 
     82 * 
     83 * (Wraps std::unique_lock for different mutex types. 
     84 *  Additionally enforces correct lock order if #define 
     85 *  RRLIB_THREAD_ENFORCE_LOCK_ORDER is enabled) 
    7886 */ 
    7987class tLock : boost::noncopyable 
     
    8896#ifndef RRLIB_SINGLE_THREADED 
    8997 
    90   explicit tLock(const tMutex& mutex) : 
    91     simple_lock(), 
    92     recursive_lock(), 
    93     locked_ordered(NULL), 
    94     locked_simple(&mutex) 
    95   { 
    96 #ifdef RRLIB_THREAD_ENFORCE_LOCK_ORDER 
    97     internal::tLockStack::Push(this); 
    98 #endif 
    99     simple_lock = std::unique_lock<std::mutex>(mutex.wrapped); 
    100   } 
    101  
    102   explicit tLock(const tNoMutex& mutex) : 
     98  /*! Creates lock not related to any mutex (cannot be locked) */ 
     99  explicit tLock() : 
    103100    simple_lock(), 
    104101    recursive_lock(), 
    105102    locked_ordered(NULL), 
    106103    locked_simple(NULL) 
    107   { 
    108   } 
    109  
    110   explicit tLock(const tOrderedMutex& mutex) : 
     104  {} 
     105 
     106  /*! 
     107   * \param mutex Mutex to lock 
     108   * \param immediately_lock Immediately lock mutex on construction of this lock? 
     109   * (If this is false, Lock() or TryLock() can be called later to acquire lock) 
     110   */ 
     111  template <typename TMutex> 
     112  inline explicit tLock(const TMutex& mutex, bool immediately_lock = true) : 
    111113    simple_lock(), 
    112114    recursive_lock(), 
    113     locked_ordered(&mutex), 
    114     locked_simple(&mutex) 
    115   { 
    116 #ifdef RRLIB_THREAD_ENFORCE_LOCK_ORDER 
    117     internal::tLockStack::Push(this); 
    118 #endif 
    119     simple_lock = std::unique_lock<std::mutex>(mutex.wrapped); 
    120   } 
    121  
    122   explicit tLock(const tRecursiveMutex& mutex) : 
     115    locked_ordered(GetLockedOrdered(mutex)), 
     116    locked_simple(GetLockedSimple(mutex)) 
     117  { 
     118    if (immediately_lock) 
     119    { 
     120      Lock(mutex); 
     121    } 
     122  } 
     123 
     124  /*! move constructor */ 
     125  explicit tLock(tLock && other) : 
    123126    simple_lock(), 
    124127    recursive_lock(), 
    125     locked_ordered(&mutex), 
    126     locked_simple() 
    127   { 
    128 #ifdef RRLIB_THREAD_ENFORCE_LOCK_ORDER 
    129     internal::tLockStack::Push(this); 
    130 #endif 
    131     recursive_lock = std::unique_lock<std::recursive_mutex>(mutex.wrapped); 
     128    locked_ordered(NULL), 
     129    locked_simple(NULL) 
     130  { 
     131    std::swap(simple_lock, other.simple_lock); 
     132    std::swap(recursive_lock, other.recursive_lock); 
     133    std::swap(locked_ordered, other.locked_ordered); 
     134    std::swap(locked_simple, other.locked_simple); 
     135  } 
     136 
     137  /*! move assignment */ 
     138  tLock& operator=(tLock && other) 
     139  { 
     140    std::swap(simple_lock, other.simple_lock); 
     141    std::swap(recursive_lock, other.recursive_lock); 
     142    std::swap(locked_ordered, other.locked_ordered); 
     143    std::swap(locked_simple, other.locked_simple); 
     144    return *this; 
    132145  } 
    133146 
     
    150163    return simple_lock; 
    151164  } 
    152  
    153 #else 
    154  
    155   template <typename T> 
    156   tLock(const T& mutex) {} 
    157  
    158   ~tLock() {} 
    159  
    160 #endif 
    161165 
    162166  /*! 
     
    171175 
    172176  /*! 
     177   * Lock (again) 
     178   */ 
     179  inline void Lock() 
     180  { 
     181    assert(((!simple_lock.owns_lock()) && (!(recursive_lock.owns_lock()))) && "Unlock before calling lock()"); 
     182    if (locked_simple) 
     183    { 
     184      Lock(*locked_simple); 
     185    } 
     186    else if (locked_ordered) 
     187    { 
     188      Lock(static_cast<const tRecursiveMutex&>(*locked_ordered)); 
     189    } 
     190  } 
     191 
     192  /*! 
     193   * Tries to acquire lock on mutex (does not block) 
     194   * 
     195   * \return True, if lock could be acquired 
     196   */ 
     197  inline bool TryLock() 
     198  { 
     199    assert(((!simple_lock.owns_lock()) && (!(recursive_lock.owns_lock()))) && "Unlock before calling lock()"); 
     200    if (locked_simple) 
     201    { 
     202      return TryLock(*locked_simple); 
     203    } 
     204    else if (locked_ordered) 
     205    { 
     206      return TryLock(static_cast<const tRecursiveMutex&>(*locked_ordered)); 
     207    } 
     208    return true; 
     209  } 
     210 
     211  /*! 
    173212   * Unlock/Release lock 
    174213   */ 
     
    193232  } 
    194233 
    195   /*! 
    196    * Lock (again) 
    197    */ 
    198   void Lock() 
    199   { 
    200     assert(((!simple_lock.owns_lock()) && (!(recursive_lock.owns_lock()))) && "Unlock before calling lock()"); 
    201     if (locked_simple) 
    202     { 
    203 #ifdef RRLIB_THREAD_ENFORCE_LOCK_ORDER 
    204       internal::tLockStack::Push(this); 
    205 #endif 
    206       simple_lock.lock(); 
    207     } 
    208     else if (locked_ordered) 
    209     { 
    210 #ifdef RRLIB_THREAD_ENFORCE_LOCK_ORDER 
    211       internal::tLockStack::Push(this); 
    212 #endif 
    213       recursive_lock.lock(); 
    214     } 
    215   } 
     234#else 
     235 
     236  tLock() {} 
     237 
     238  template <typename T> 
     239  tLock(const T& mutex) {} 
     240 
     241  template <typename T1, typename T2> 
     242  tLock(const T& mutex, T2 parameter) {} 
     243 
     244  ~tLock() {} 
     245 
     246#endif 
     247 
    216248 
    217249//---------------------------------------------------------------------- 
     
    230262  const tMutex* locked_simple; 
    231263 
    232 #endif 
     264 
     265  // Internal helper methods to handle different variants of mutexes uniformly in constructors 
     266 
     267  inline const tOrderedMutexBaseClass* GetLockedOrdered(const tMutex& mutex) 
     268  { 
     269    return NULL; 
     270  } 
     271  inline const tOrderedMutexBaseClass* GetLockedOrdered(const tNoMutex& mutex) 
     272  { 
     273    return NULL; 
     274  } 
     275  inline const tOrderedMutexBaseClass* GetLockedOrdered(const tOrderedMutex& mutex) 
     276  { 
     277    return &mutex; 
     278  } 
     279  inline const tOrderedMutexBaseClass* GetLockedOrdered(const tRecursiveMutex& mutex) 
     280  { 
     281    return &mutex; 
     282  } 
     283  inline const tMutex* GetLockedSimple(const tMutex& mutex) 
     284  { 
     285    return &mutex; 
     286  } 
     287  inline const tMutex* GetLockedSimple(const tNoMutex& mutex) 
     288  { 
     289    return NULL; 
     290  } 
     291  inline const tMutex* GetLockedSimple(const tOrderedMutex& mutex) 
     292  { 
     293    return &mutex; 
     294  } 
     295  inline const tMutex* GetLockedSimple(const tRecursiveMutex& mutex) 
     296  { 
     297    return NULL; 
     298  } 
     299 
     300  inline void Lock(const tNoMutex& mutex) {} 
     301  inline void Lock(const tMutex& mutex) 
     302  { 
     303#ifdef RRLIB_THREAD_ENFORCE_LOCK_ORDER 
     304    internal::tLockStack::Push(this); 
     305#endif 
     306    simple_lock = std::unique_lock<std::mutex>(mutex.wrapped); 
     307  } 
     308  inline void Lock(const tRecursiveMutex& mutex) 
     309  { 
     310#ifdef RRLIB_THREAD_ENFORCE_LOCK_ORDER 
     311    internal::tLockStack::Push(this); 
     312#endif 
     313    recursive_lock = std::unique_lock<std::recursive_mutex>(mutex.wrapped); 
     314  } 
     315 
     316  inline bool TryLock(const tNoMutex& mutex) 
     317  { 
     318    return true; 
     319  } 
     320  inline bool TryLock(const tMutex& mutex) 
     321  { 
     322    simple_lock = std::unique_lock<std::mutex>(mutex.wrapped, std::defer_lock_t()); 
     323    bool locked = simple_lock.try_lock(); 
     324    if (locked) 
     325    { 
     326#ifdef RRLIB_THREAD_ENFORCE_LOCK_ORDER 
     327      internal::tLockStack::Push(this); 
     328#endif 
     329    } 
     330    return locked; 
     331  } 
     332  inline bool TryLock(const tRecursiveMutex& mutex) 
     333  { 
     334    recursive_lock = std::unique_lock<std::recursive_mutex>(mutex.wrapped, std::defer_lock_t()); 
     335    bool locked = recursive_lock.try_lock(); 
     336    if (locked) 
     337    { 
     338#ifdef RRLIB_THREAD_ENFORCE_LOCK_ORDER 
     339      internal::tLockStack::Push(this); 
     340#endif 
     341    } 
     342    return locked; 
     343  } 
     344 
     345#endif 
     346 
     347 
    233348}; 
    234349 
  • tThread.cpp

    r7 r8  
    359359  // run thread? 
    360360  state = tState::RUNNING; 
    361   if (start_signal && (!(stop_signal))) 
     361  if (start_signal/* && (!(stop_signal))*/) 
    362362  { 
    363363    l.Unlock(); 
     
    459459  if (time_mode == rrlib::time::tTimeMode::SYSTEM_TIME || (!use_application_time)) 
    460460  { 
    461     if (sleep_for <= std::chrono::milliseconds(500)) 
     461    if (sleep_for < std::chrono::milliseconds(400)) 
    462462    { 
    463463      std::this_thread::sleep_for(sleep_for); 
Note: See TracChangeset for help on using the changeset viewer.