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