recursive_lock.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. //
  2. // recursive_lock.h
  3. // threadpp
  4. //
  5. // Created by Melo Yao on 1/16/15.
  6. // Copyright (c) 2015 Melo Yao. All rights reserved.
  7. //
  8. #ifndef threadpp_recursive_lock_h
  9. #define threadpp_recursive_lock_h
  10. #include "threadpp_assert.h"
  11. namespace threadpp
  12. {
  13. template <typename locktype,typename threadtype>
  14. class recursive_lock
  15. {
  16. locktype _lock;
  17. volatile typename threadtype::id_type _owner;
  18. volatile unsigned int _count;
  19. public:
  20. recursive_lock();
  21. void lock();
  22. void unlock();
  23. void wait();
  24. void wait(unsigned long millisecs);
  25. void notify();
  26. void notify_all();
  27. };
  28. template <typename locktype,typename threadtype>
  29. recursive_lock<locktype,threadtype>::recursive_lock():_owner(threadtype::null_id()),_count(0)
  30. {
  31. }
  32. template <typename locktype,typename threadtype>
  33. void recursive_lock<locktype,threadtype>::lock()
  34. {
  35. typename threadtype::id_type tid = threadtype::current_thread_id();
  36. if(tid == _owner)
  37. {
  38. _count++;
  39. }
  40. else
  41. {
  42. _lock.lock();
  43. _owner = tid;
  44. _count=1;
  45. }
  46. }
  47. template <typename locktype,typename threadtype>
  48. void recursive_lock<locktype,threadtype>::unlock()
  49. {
  50. typename threadtype::id_type tid = threadtype::current_thread_id();
  51. ASSERT(tid == _owner,"%s", "unlock failed,try to unlock not owned mutex");
  52. _count--;
  53. if (_count == 0) {
  54. _owner = threadtype::null_id();
  55. _lock.unlock();
  56. }
  57. }
  58. template <typename locktype,typename threadtype>
  59. void recursive_lock<locktype,threadtype>::wait()
  60. {
  61. typename threadtype::id_type owner = _owner;
  62. unsigned count = _count;
  63. _owner = threadtype::null_id();
  64. _count = 0;
  65. _lock.wait();
  66. _owner = owner;
  67. _count = count;
  68. }
  69. template <typename locktype,typename threadtype>
  70. void recursive_lock<locktype,threadtype>::wait(unsigned long millisecs)
  71. {
  72. typename threadtype::id_type owner = _owner;
  73. unsigned count = _count;
  74. _owner = threadtype::null_id();
  75. _count = 0;
  76. _lock.wait(millisecs);
  77. _owner = owner;
  78. _count = count;
  79. }
  80. template <typename locktype,typename threadtype>
  81. void recursive_lock<locktype,threadtype>::notify()
  82. {
  83. _lock.notify();
  84. }
  85. template <typename locktype,typename threadtype>
  86. void recursive_lock<locktype,threadtype>::notify_all()
  87. {
  88. _lock.notify_all();
  89. }
  90. }
  91. #endif