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