2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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
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.
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.
31 #ifndef ThreadRestrictionVerifier_h
32 #define ThreadRestrictionVerifier_h
34 #include <wtf/Assertions.h>
35 #include <wtf/Threading.h>
36 #include <wtf/ThreadingPrimitives.h>
39 #include <dispatch/dispatch.h>
46 // Verifies that a class is used in a way that respects its lack of thread-safety.
47 // The default mode is to verify that the object will only be used on a single thread. The
48 // thread gets captured when setShared(true) is called.
49 // The mode may be changed by calling useMutexMode (or turnOffVerification).
50 class ThreadRestrictionVerifier {
52 ThreadRestrictionVerifier()
53 : m_mode(SingleThreadVerificationMode)
64 ~ThreadRestrictionVerifier()
67 dispatch_release(m_owningQueue);
71 void setMutexMode(Mutex& mutex)
73 ASSERT(m_mode == SingleThreadVerificationMode || (m_mode == MutexVerificationMode && &mutex == m_mutex));
74 m_mode = MutexVerificationMode;
79 void setDispatchQueueMode(dispatch_queue_t queue)
81 ASSERT(m_mode == SingleThreadVerificationMode);
82 m_mode = SingleDispatchQueueVerificationMode;
83 m_owningQueue = queue;
84 dispatch_retain(m_owningQueue);
88 void turnOffVerification()
90 ASSERT(m_mode == SingleThreadVerificationMode);
91 m_mode = NoVerificationMode;
94 // Indicates that the object may (or may not) be owned by more than one place.
95 void setShared(bool shared)
98 bool previouslyShared = m_shared;
106 case SingleThreadVerificationMode:
107 ASSERT(shared != previouslyShared);
108 // Capture the current thread to verify that subsequent ref/deref happen on this thread.
109 m_owningThread = currentThread();
113 case SingleDispatchQueueVerificationMode:
115 case MutexVerificationMode:
116 case NoVerificationMode:
119 ASSERT_NOT_REACHED();
122 // Is it OK to use the object at this moment on the current thread?
123 bool isSafeToUse() const
129 case SingleThreadVerificationMode:
130 return m_owningThread == currentThread();
132 case MutexVerificationMode:
133 if (!m_mutex->tryLock())
139 case SingleDispatchQueueVerificationMode:
140 return m_owningQueue == dispatch_get_current_queue();
143 case NoVerificationMode:
146 ASSERT_NOT_REACHED();
151 enum VerificationMode {
152 SingleThreadVerificationMode,
153 MutexVerificationMode,
156 SingleDispatchQueueVerificationMode,
160 VerificationMode m_mode;
163 // Used by SingleThreadVerificationMode
164 ThreadIdentifier m_owningThread;
166 // Used by MutexVerificationMode.
170 // Used by SingleDispatchQueueVerificationMode.
171 dispatch_queue_t m_owningQueue;