1 /* 2 * Copyright (C) 2007, 2008, 2010 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 31 #ifndef ThreadingPrimitives_h 32 #define ThreadingPrimitives_h 33 34 #include "Platform.h" 35 36 #include <wtf/Assertions.h> 37 #include <wtf/FastAllocBase.h> 38 #include <wtf/Locker.h> 39 #include <wtf/Noncopyable.h> 40 41 #if OS(WINDOWS) 42 #include <windows.h> 43 #endif 44 45 #if USE(PTHREADS) 46 #include <pthread.h> 47 #elif PLATFORM(GTK) 48 #include "GOwnPtr.h" 49 #endif 50 51 #if PLATFORM(QT) 52 #include <qglobal.h> 53 QT_BEGIN_NAMESPACE 54 class QMutex; 55 class QWaitCondition; 56 QT_END_NAMESPACE 57 #endif 58 59 namespace WTF { 60 61 #if USE(PTHREADS) 62 typedef pthread_mutex_t PlatformMutex; 63 #if HAVE(PTHREAD_RWLOCK) 64 typedef pthread_rwlock_t PlatformReadWriteLock; 65 #else 66 typedef void* PlatformReadWriteLock; 67 #endif 68 typedef pthread_cond_t PlatformCondition; 69 #elif PLATFORM(GTK) 70 typedef GOwnPtr<GMutex> PlatformMutex; 71 typedef void* PlatformReadWriteLock; // FIXME: Implement. 72 typedef GOwnPtr<GCond> PlatformCondition; 73 #elif PLATFORM(QT) 74 typedef QT_PREPEND_NAMESPACE(QMutex)* PlatformMutex; 75 typedef void* PlatformReadWriteLock; // FIXME: Implement. 76 typedef QT_PREPEND_NAMESPACE(QWaitCondition)* PlatformCondition; 77 #elif OS(WINDOWS) 78 struct PlatformMutex { 79 CRITICAL_SECTION m_internalMutex; 80 size_t m_recursionCount; 81 }; 82 typedef void* PlatformReadWriteLock; // FIXME: Implement. 83 struct PlatformCondition { 84 size_t m_waitersGone; 85 size_t m_waitersBlocked; 86 size_t m_waitersToUnblock; 87 HANDLE m_blockLock; 88 HANDLE m_blockQueue; 89 HANDLE m_unblockLock; 90 91 bool timedWait(PlatformMutex&, DWORD durationMilliseconds); 92 void signal(bool unblockAll); 93 }; 94 #else 95 typedef void* PlatformMutex; 96 typedef void* PlatformReadWriteLock; 97 typedef void* PlatformCondition; 98 #endif 99 100 class Mutex { 101 WTF_MAKE_NONCOPYABLE(Mutex); WTF_MAKE_FAST_ALLOCATED; 102 public: 103 Mutex(); 104 ~Mutex(); 105 106 void lock(); 107 bool tryLock(); 108 void unlock(); 109 110 public: impl()111 PlatformMutex& impl() { return m_mutex; } 112 private: 113 PlatformMutex m_mutex; 114 }; 115 116 typedef Locker<Mutex> MutexLocker; 117 118 class ReadWriteLock { 119 WTF_MAKE_NONCOPYABLE(ReadWriteLock); 120 public: 121 ReadWriteLock(); 122 ~ReadWriteLock(); 123 124 void readLock(); 125 bool tryReadLock(); 126 127 void writeLock(); 128 bool tryWriteLock(); 129 130 void unlock(); 131 132 private: 133 PlatformReadWriteLock m_readWriteLock; 134 }; 135 136 class ThreadCondition { 137 WTF_MAKE_NONCOPYABLE(ThreadCondition); 138 public: 139 ThreadCondition(); 140 ~ThreadCondition(); 141 142 void wait(Mutex& mutex); 143 // Returns true if the condition was signaled before absoluteTime, false if the absoluteTime was reached or is in the past. 144 // The absoluteTime is in seconds, starting on January 1, 1970. The time is assumed to use the same time zone as WTF::currentTime(). 145 bool timedWait(Mutex&, double absoluteTime); 146 void signal(); 147 void broadcast(); 148 149 private: 150 PlatformCondition m_condition; 151 }; 152 153 #if OS(WINDOWS) 154 // The absoluteTime is in seconds, starting on January 1, 1970. The time is assumed to use the same time zone as WTF::currentTime(). 155 // Returns an interval in milliseconds suitable for passing to one of the Win32 wait functions (e.g., ::WaitForSingleObject). 156 DWORD absoluteTimeToWaitTimeoutInterval(double absoluteTime); 157 #endif 158 159 } // namespace WTF 160 161 using WTF::Mutex; 162 using WTF::MutexLocker; 163 using WTF::ThreadCondition; 164 165 #if OS(WINDOWS) 166 using WTF::absoluteTimeToWaitTimeoutInterval; 167 #endif 168 169 #endif // ThreadingPrimitives_h 170