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