ddb38d1ff62bf8c76bd3e18c4b8c172ecabc44f6
[WebKit-https.git] / WebCore / platform / Threading.h
1 /*
2  * Copyright (C) 2007 Apple Inc. All rights reserved.
3  * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer. 
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution. 
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission. 
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #ifndef Threading_h
31 #define Threading_h
32
33 #include <wtf/Assertions.h>
34 #include <wtf/Noncopyable.h>
35
36 #if USE(PTHREADS)
37 #include <pthread.h>
38 #endif
39
40 #if PLATFORM(GTK)
41 typedef struct _GMutex GMutex;
42 typedef struct _GCond GCond;
43 #endif
44
45 #if PLATFORM(QT)
46 class QMutex;
47 class QWaitCondition;
48 #endif
49
50 #include <stdint.h>
51
52 namespace WebCore {
53
54 typedef uint32_t ThreadIdentifier;
55 typedef void* (*ThreadFunction)(void* argument);
56
57 // Returns 0 if thread creation failed
58 ThreadIdentifier createThread(ThreadFunction, void*);
59 ThreadIdentifier currentThread();
60 int waitForThreadCompletion(ThreadIdentifier, void**);
61 void detachThread(ThreadIdentifier);
62
63 #if USE(PTHREADS)
64 typedef pthread_mutex_t PlatformMutex;
65 typedef pthread_cond_t PlatformCondition;
66 #elif PLATFORM(GTK)
67 typedef GMutex* PlatformMutex;
68 typedef GCond* PlatformCondition;
69 #elif PLATFORM(QT)
70 typedef QMutex* PlatformMutex;
71 typedef QWaitCondition* PlatformCondition;
72 #elif PLATFORM(WIN_OS)
73 struct PlatformMutex {
74     CRITICAL_SECTION m_internalMutex;
75     size_t m_recursionCount;
76 };
77 struct PlatformCondition {
78     size_t m_timedOut;
79     size_t m_blocked;
80     size_t m_waitingForRemoval;
81     HANDLE m_gate;
82     HANDLE m_queue;
83     HANDLE m_mutex;
84 };
85 #else
86 typedef void* PlatformMutex;
87 typedef void* PlatformCondition;
88 #endif
89     
90 class Mutex : Noncopyable {
91 public:
92     Mutex();
93     ~Mutex();
94
95     void lock();
96     bool tryLock();
97     void unlock();
98
99 public:
100     PlatformMutex& impl() { return m_mutex; }
101 private:
102     PlatformMutex m_mutex;
103 };
104
105 class MutexLocker : Noncopyable {
106 public:
107     MutexLocker(Mutex& mutex) : m_mutex(mutex) { m_mutex.lock(); }
108     ~MutexLocker() { m_mutex.unlock(); }
109
110 private:
111     Mutex& m_mutex;
112 };
113
114 class ThreadCondition : Noncopyable {
115 public:
116     ThreadCondition();
117     ~ThreadCondition();
118     
119     void wait(Mutex& mutex);
120     void signal();
121     void broadcast();
122     
123 private:
124     PlatformCondition m_condition;
125 };
126     
127 template<class T> class ThreadSafeShared : Noncopyable {
128 public:
129     ThreadSafeShared()
130         : m_refCount(0)
131 #ifndef NDEBUG
132         , m_inDestructor(0)
133 #endif
134     {
135     }
136
137     void ref()
138     {
139         MutexLocker locker(m_mutex);
140         ASSERT(!m_inDestructor);
141         ++m_refCount;
142     }
143
144     void deref()
145     {
146         {
147             MutexLocker locker(m_mutex);
148             ASSERT(!m_inDestructor);
149             --m_refCount;
150         }
151         
152         if (m_refCount <= 0) {
153 #ifndef NDEBUG
154             m_inDestructor = true;
155 #endif
156             delete static_cast<T*>(this);
157         }
158     }
159
160     bool hasOneRef()
161     {
162         MutexLocker locker(m_mutex);
163         ASSERT(!m_inDestructor);
164         return m_refCount == 1;
165     }
166
167     int refCount() const
168     {
169         MutexLocker locker(m_mutex);
170         return m_refCount;
171     }
172
173     bool isThreadSafe() { return true; }
174     
175 private:
176     mutable Mutex m_mutex;
177     int m_refCount;
178 #ifndef NDEBUG
179     bool m_inDestructor;
180 #endif
181 };
182
183 void callOnMainThread(void (*)());
184
185 void initializeThreading();
186
187 #if !PLATFORM(WIN) && !PLATFORM(GTK)
188 inline void initializeThreading()
189 {
190 }
191 #endif
192
193 } // namespace WebCore
194
195 #endif // Threading_h