Merge "Fix build break by removing TIZEN_RECORDING_SURFACE_SET" into tizen_2.1
[framework/web/webkit-efl.git] / Source / WTF / wtf / ThreadRestrictionVerifier.h
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
31 #ifndef ThreadRestrictionVerifier_h
32 #define ThreadRestrictionVerifier_h
33
34 #include <wtf/Assertions.h>
35 #include <wtf/Threading.h>
36 #include <wtf/ThreadingPrimitives.h>
37
38 #if HAVE(DISPATCH_H)
39 #include <dispatch/dispatch.h>
40 #endif
41
42 #ifndef NDEBUG
43
44 namespace WTF {
45
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 {
51 public:
52     ThreadRestrictionVerifier()
53         : m_mode(SingleThreadVerificationMode)
54         , m_shared(false)
55         , m_owningThread(0)
56         , m_mutex(0)
57 #if HAVE(DISPATCH_H)
58         , m_owningQueue(0)
59 #endif
60     {
61     }
62
63 #if HAVE(DISPATCH_H)
64     ~ThreadRestrictionVerifier()
65     {
66         if (m_owningQueue)
67             dispatch_release(m_owningQueue);
68     }
69 #endif
70
71     void setMutexMode(Mutex& mutex)
72     {
73         ASSERT(m_mode == SingleThreadVerificationMode || (m_mode == MutexVerificationMode && &mutex == m_mutex));
74         m_mode = MutexVerificationMode;
75         m_mutex = &mutex;
76     }
77
78 #if HAVE(DISPATCH_H)
79     void setDispatchQueueMode(dispatch_queue_t queue)
80     {
81         ASSERT(m_mode == SingleThreadVerificationMode);
82         m_mode = SingleDispatchQueueVerificationMode;
83         m_owningQueue = queue;
84         dispatch_retain(m_owningQueue);
85     }
86 #endif
87
88     void turnOffVerification()
89     {
90         ASSERT(m_mode == SingleThreadVerificationMode);
91         m_mode = NoVerificationMode;
92     }
93
94     // Indicates that the object may (or may not) be owned by more than one place.
95     void setShared(bool shared)
96     {
97 #if !ASSERT_DISABLED
98         bool previouslyShared = m_shared;
99 #endif
100         m_shared = shared;
101
102         if (!m_shared)
103             return;
104
105         switch (m_mode) {
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();
110             return;
111
112 #if HAVE(DISPATCH_H)
113         case SingleDispatchQueueVerificationMode:
114 #endif
115         case MutexVerificationMode:
116         case NoVerificationMode:
117             return;
118         }
119         ASSERT_NOT_REACHED();
120     }
121
122     // Is it OK to use the object at this moment on the current thread?
123     bool isSafeToUse() const
124     {
125         if (!m_shared)
126             return true;
127
128         switch (m_mode) {
129         case SingleThreadVerificationMode:
130             return m_owningThread == currentThread();
131
132         case MutexVerificationMode:
133             if (!m_mutex->tryLock())
134                 return true;
135             m_mutex->unlock();
136             return false;
137
138 #if HAVE(DISPATCH_H)
139         case SingleDispatchQueueVerificationMode:
140             return m_owningQueue == dispatch_get_current_queue();
141 #endif
142
143         case NoVerificationMode:
144             return true;
145         }
146         ASSERT_NOT_REACHED();
147         return true;
148     }
149
150 private:
151     enum VerificationMode {
152         SingleThreadVerificationMode,
153         MutexVerificationMode,
154         NoVerificationMode,
155 #if HAVE(DISPATCH_H)
156         SingleDispatchQueueVerificationMode,
157 #endif
158     };
159
160     VerificationMode m_mode;
161     bool m_shared;
162
163     // Used by SingleThreadVerificationMode
164     ThreadIdentifier m_owningThread;
165
166     // Used by MutexVerificationMode.
167     Mutex* m_mutex;
168
169 #if HAVE(DISPATCH_H)
170     // Used by SingleDispatchQueueVerificationMode.
171     dispatch_queue_t m_owningQueue;
172 #endif
173 };
174
175 }
176
177 #endif
178 #endif