object_level_lock.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
  2. // vim:tabstop=4:shiftwidth=4:expandtab:
  3. /*
  4. * Copyright (C) 2004-2008 Wu Yongwei <adah at users dot sourceforge dot net>
  5. *
  6. * This software is provided 'as-is', without any express or implied
  7. * warranty. In no event will the authors be held liable for any
  8. * damages arising from the use of this software.
  9. *
  10. * Permission is granted to anyone to use this software for any purpose,
  11. * including commercial applications, and to alter it and redistribute
  12. * it freely, subject to the following restrictions:
  13. *
  14. * 1. The origin of this software must not be misrepresented; you must
  15. * not claim that you wrote the original software. If you use this
  16. * software in a product, an acknowledgement in the product
  17. * documentation would be appreciated but is not required.
  18. * 2. Altered source versions must be plainly marked as such, and must
  19. * not be misrepresented as being the original software.
  20. * 3. This notice may not be removed or altered from any source
  21. * distribution.
  22. *
  23. * This file is part of Stones of Nvwa:
  24. * http://sourceforge.net/projects/nvwa
  25. *
  26. */
  27. /*!
  28. * \file object_level_lock.h
  29. * \ingroup QxMemLeak
  30. *
  31. * In essence Loki ObjectLevelLockable re-engineered to use a fast_mutex
  32. * class. Check also Andrei Alexandrescu's article <a
  33. * href="http://www.awprofessional.com/articles/article.asp?p=25298">
  34. * "Multithreading and the C++ Type System"</a> for the ideas behind.
  35. *
  36. * \version 1.4, 2004/05/09
  37. * \author Wu Yongwei
  38. *
  39. */
  40. #ifndef QT_NO_DEBUG
  41. #ifndef _QX_MODE_RELEASE
  42. #if _QX_USE_MEM_LEAK_DETECTION
  43. #ifndef _OBJECT_LEVEL_LOCK_H
  44. #define _OBJECT_LEVEL_LOCK_H
  45. #ifdef _MSC_VER
  46. #pragma once
  47. #endif
  48. #include "fast_mutex.h"
  49. namespace qx {
  50. namespace memory {
  51. # ifdef _NOTHREADS
  52. /**
  53. * Helper class for object-level locking. This is the
  54. * single-threaded implementation.
  55. */
  56. template <class _Host>
  57. class object_level_lock
  58. {
  59. public:
  60. /** Type that provides locking/unlocking semantics. */
  61. class lock
  62. {
  63. #ifndef _QX_MODE_RELEASE
  64. #ifndef QT_NO_DEBUG
  65. const object_level_lock& _M_host;
  66. #endif // QT_NO_DEBUG
  67. #endif // _QX_MODE_RELEASE
  68. lock(const lock&);
  69. lock& operator=(const lock&);
  70. public:
  71. explicit lock(const object_level_lock& __host)
  72. #ifndef _QX_MODE_RELEASE
  73. #ifndef QT_NO_DEBUG
  74. : _M_host(__host)
  75. #endif // QT_NO_DEBUG
  76. #endif // _QX_MODE_RELEASE
  77. {}
  78. #ifndef _QX_MODE_RELEASE
  79. #ifndef QT_NO_DEBUG
  80. // The purpose of this method is allow one to write code
  81. // like "assert(guard.get_locked_object() == this)" to
  82. // ensure that the locked object is exactly the object being
  83. // accessed.
  84. const object_level_lock* get_locked_object() const
  85. {
  86. return &_M_host;
  87. }
  88. #endif // QT_NO_DEBUG
  89. #endif // _QX_MODE_RELEASE
  90. };
  91. typedef _Host volatile_type;
  92. };
  93. # else
  94. /**
  95. * Helper class for class-level locking. This is the multi-threaded
  96. * implementation.
  97. */
  98. template <class _Host>
  99. class object_level_lock
  100. {
  101. mutable fast_mutex _M_mtx;
  102. public:
  103. class lock;
  104. friend class lock;
  105. /** Type that provides locking/unlocking semantics. */
  106. class lock
  107. {
  108. const object_level_lock& _M_host;
  109. lock(const lock&);
  110. lock& operator=(const lock&);
  111. public:
  112. explicit lock(const object_level_lock& __host) : _M_host(__host)
  113. {
  114. _M_host._M_mtx.lock();
  115. }
  116. ~lock()
  117. {
  118. _M_host._M_mtx.unlock();
  119. }
  120. #ifndef _QX_MODE_RELEASE
  121. #ifndef QT_NO_DEBUG
  122. // The purpose of this method is allow one to write code
  123. // like "assert(guard.get_locked_object() == this)" to
  124. // ensure that the locked object is exactly the object being
  125. // accessed.
  126. const object_level_lock* get_locked_object() const
  127. {
  128. return &_M_host;
  129. }
  130. #endif // QT_NO_DEBUG
  131. #endif // _QX_MODE_RELEASE
  132. };
  133. typedef volatile _Host volatile_type;
  134. };
  135. # endif // _NOTHREADS
  136. } // namespace memory
  137. } // namespace qx
  138. #endif // _OBJECT_LEVEL_LOCK_H
  139. #endif // _QX_USE_MEM_LEAK_DETECTION
  140. #endif // _QX_MODE_RELEASE
  141. #endif // QT_NO_DEBUG