ThreadRestrictionVerifier.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. * Copyright (C) 2011 Google Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are
  6. * met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above
  11. * copyright notice, this list of conditions and the following disclaimer
  12. * in the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Google Inc. nor the names of its
  15. * contributors may be used to endorse or promote products derived from
  16. * this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #ifndef ThreadRestrictionVerifier_h
  31. #define ThreadRestrictionVerifier_h
  32. #include <wtf/Assertions.h>
  33. #include <wtf/Threading.h>
  34. #include <wtf/ThreadingPrimitives.h>
  35. #if HAVE(DISPATCH_H)
  36. #include <dispatch/dispatch.h>
  37. #endif
  38. #ifndef NDEBUG
  39. namespace WTF {
  40. // Verifies that a class is used in a way that respects its lack of thread-safety.
  41. // The default mode is to verify that the object will only be used on a single thread. The
  42. // thread gets captured when setShared(true) is called.
  43. // The mode may be changed by calling useMutexMode (or turnOffVerification).
  44. // FIXME: This verifier is switched off because it fires false positives for
  45. // objects that are used on multiple threads. Instead of an opt-out verifier,
  46. // we probably need an opt-in verifier that marks select objects as being
  47. // tied to select threads.
  48. #if 0
  49. class ThreadRestrictionVerifier {
  50. public:
  51. ThreadRestrictionVerifier()
  52. : m_mode(SingleThreadVerificationMode)
  53. , m_shared(false)
  54. , m_owningThread(0)
  55. , m_mutex(0)
  56. #if HAVE(DISPATCH_H)
  57. , m_owningQueue(0)
  58. #endif
  59. {
  60. }
  61. #if HAVE(DISPATCH_H)
  62. ~ThreadRestrictionVerifier()
  63. {
  64. if (m_owningQueue)
  65. dispatch_release(m_owningQueue);
  66. }
  67. #endif
  68. void setMutexMode(Mutex& mutex)
  69. {
  70. m_mode = MutexVerificationMode;
  71. m_mutex = &mutex;
  72. }
  73. #if HAVE(DISPATCH_H)
  74. void setDispatchQueueMode(dispatch_queue_t queue)
  75. {
  76. m_mode = SingleDispatchQueueVerificationMode;
  77. m_owningQueue = queue;
  78. dispatch_retain(m_owningQueue);
  79. }
  80. #endif
  81. void turnOffVerification()
  82. {
  83. m_mode = NoVerificationMode;
  84. }
  85. // Indicates that the object may (or may not) be owned by more than one place.
  86. void setShared(bool shared)
  87. {
  88. #if !ASSERT_DISABLED
  89. bool previouslyShared = m_shared;
  90. #endif
  91. m_shared = shared;
  92. if (!m_shared)
  93. return;
  94. switch (m_mode) {
  95. case SingleThreadVerificationMode:
  96. ASSERT(shared != previouslyShared);
  97. // Capture the current thread to verify that subsequent ref/deref happen on this thread.
  98. m_owningThread = currentThread();
  99. return;
  100. #if HAVE(DISPATCH_H)
  101. case SingleDispatchQueueVerificationMode:
  102. #endif
  103. case MutexVerificationMode:
  104. case NoVerificationMode:
  105. return;
  106. }
  107. ASSERT_NOT_REACHED();
  108. }
  109. // Is it OK to use the object at this moment on the current thread?
  110. bool isSafeToUse() const
  111. {
  112. if (!m_shared)
  113. return true;
  114. switch (m_mode) {
  115. case SingleThreadVerificationMode:
  116. return m_owningThread == currentThread();
  117. case MutexVerificationMode:
  118. if (!m_mutex->tryLock())
  119. return true;
  120. m_mutex->unlock();
  121. return false;
  122. #if HAVE(DISPATCH_H)
  123. case SingleDispatchQueueVerificationMode:
  124. return m_owningQueue == dispatch_get_current_queue();
  125. #endif
  126. case NoVerificationMode:
  127. return true;
  128. }
  129. ASSERT_NOT_REACHED();
  130. return true;
  131. }
  132. private:
  133. enum VerificationMode {
  134. SingleThreadVerificationMode,
  135. MutexVerificationMode,
  136. NoVerificationMode,
  137. #if HAVE(DISPATCH_H)
  138. SingleDispatchQueueVerificationMode,
  139. #endif
  140. };
  141. VerificationMode m_mode;
  142. bool m_shared;
  143. // Used by SingleThreadVerificationMode
  144. ThreadIdentifier m_owningThread;
  145. // Used by MutexVerificationMode.
  146. Mutex* m_mutex;
  147. #if HAVE(DISPATCH_H)
  148. // Used by SingleDispatchQueueVerificationMode.
  149. dispatch_queue_t m_owningQueue;
  150. #endif
  151. };
  152. #else
  153. class ThreadRestrictionVerifier {
  154. public:
  155. ThreadRestrictionVerifier()
  156. {
  157. }
  158. void setMutexMode(Mutex&)
  159. {
  160. }
  161. #if HAVE(DISPATCH_H)
  162. void setDispatchQueueMode(dispatch_queue_t)
  163. {
  164. }
  165. #endif
  166. void turnOffVerification()
  167. {
  168. }
  169. // Indicates that the object may (or may not) be owned by more than one place.
  170. void setShared(bool)
  171. {
  172. }
  173. // Is it OK to use the object at this moment on the current thread?
  174. bool isSafeToUse() const
  175. {
  176. return true;
  177. }
  178. };
  179. #endif
  180. }
  181. #endif
  182. #endif