UnlockGuard.h 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * UnlockGuard.h, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #pragma once
  11. VCMI_LIB_NAMESPACE_BEGIN
  12. namespace vstd
  13. {
  14. namespace detail
  15. {
  16. template<typename Mutex>
  17. class unlock_policy
  18. {
  19. protected:
  20. void unlock(Mutex &m)
  21. {
  22. m.unlock();
  23. }
  24. void lock(Mutex &m)
  25. {
  26. m.lock();
  27. }
  28. };
  29. template<typename Mutex>
  30. class unlock_shared_policy
  31. {
  32. protected:
  33. void unlock(Mutex &m)
  34. {
  35. m.unlock_shared();
  36. }
  37. void lock(Mutex &m)
  38. {
  39. m.lock_shared();
  40. }
  41. };
  42. }
  43. //similar to std::lock_guard but UNlocks for the scope + assertions
  44. template<typename Mutex, typename LockingPolicy = detail::unlock_policy<Mutex> >
  45. class unlock_guard : LockingPolicy
  46. {
  47. private:
  48. Mutex* m;
  49. explicit unlock_guard(unlock_guard&);
  50. unlock_guard& operator=(unlock_guard&);
  51. public:
  52. explicit unlock_guard(Mutex& m_):
  53. m(&m_)
  54. {
  55. this->unlock(*m);
  56. }
  57. unlock_guard()
  58. {
  59. m = nullptr;
  60. }
  61. unlock_guard(unlock_guard &&other)
  62. : m(other.m)
  63. {
  64. other.m = nullptr;
  65. }
  66. void release()
  67. {
  68. m = nullptr;
  69. }
  70. ~unlock_guard()
  71. {
  72. if(m)
  73. this->lock(*m);
  74. }
  75. };
  76. template<typename Mutex>
  77. unlock_guard<Mutex, detail::unlock_policy<Mutex> > makeUnlockGuard(Mutex &m_)
  78. {
  79. return unlock_guard<Mutex, detail::unlock_policy<Mutex> >(m_);
  80. }
  81. template<typename Mutex>
  82. unlock_guard<Mutex, detail::unlock_shared_policy<Mutex> > makeUnlockSharedGuard(Mutex &m_)
  83. {
  84. return unlock_guard<Mutex, detail::unlock_shared_policy<Mutex> >(m_);
  85. }
  86. using unlock_shared_guard = unlock_guard<std::shared_mutex, detail::unlock_shared_policy<std::shared_mutex>>;
  87. }
  88. VCMI_LIB_NAMESPACE_END