1 /////////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (c) 2005, Industrial Light & Magic, a division of Lucas 4 // Digital Ltd. LLC 5 // 6 // All rights reserved. 7 // 8 // Redistribution and use in source and binary forms, with or without 9 // modification, are permitted provided that the following conditions are 10 // met: 11 // * Redistributions of source code must retain the above copyright 12 // notice, this list of conditions and the following disclaimer. 13 // * Redistributions in binary form must reproduce the above 14 // copyright notice, this list of conditions and the following disclaimer 15 // in the documentation and/or other materials provided with the 16 // distribution. 17 // * Neither the name of Industrial Light & Magic nor the names of 18 // its contributors may be used to endorse or promote products derived 19 // from this software without specific prior written permission. 20 // 21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 // 33 /////////////////////////////////////////////////////////////////////////// 34 35 #ifndef INCLUDED_ILM_THREAD_MUTEX_H 36 #define INCLUDED_ILM_THREAD_MUTEX_H 37 38 //----------------------------------------------------------------------------- 39 // 40 // class Mutex, class Lock 41 // 42 // Class Mutex is a wrapper for a system-dependent mutual exclusion 43 // mechanism. Actual locking and unlocking of a Mutex object must 44 // be performed using an instance of a Lock (defined below). 45 // 46 // Class lock provides safe locking and unlocking of mutexes even in 47 // the presence of C++ exceptions. Constructing a Lock object locks 48 // the mutex; destroying the Lock unlocks the mutex. 49 // 50 // Lock objects are not themselves thread-safe. You should never 51 // share a Lock object among multiple threads. 52 // 53 // Typical usage: 54 // 55 // Mutex mtx; // Create a Mutex object that is visible 56 // //to multiple threads 57 // 58 // ... // create some threads 59 // 60 // // Then, within each thread, construct a critical section like so: 61 // 62 // { 63 // Lock lock (mtx); // Lock constructor locks the mutex 64 // ... // do some computation on shared data 65 // } // leaving the block unlocks the mutex 66 // 67 //----------------------------------------------------------------------------- 68 69 #include "IlmBaseConfig.h" 70 71 #if defined _WIN32 || defined _WIN64 72 #ifdef NOMINMAX 73 #undef NOMINMAX 74 #endif 75 #define NOMINMAX 76 #include <windows.h> 77 #elif HAVE_PTHREAD 78 #include <pthread.h> 79 #endif 80 81 namespace IlmThread { 82 83 class Lock; 84 85 86 class Mutex 87 { 88 public: 89 90 Mutex (); 91 virtual ~Mutex (); 92 93 private: 94 95 void lock () const; 96 void unlock () const; 97 98 #if defined _WIN32 || defined _WIN64 99 mutable CRITICAL_SECTION _mutex; 100 #elif HAVE_PTHREAD 101 mutable pthread_mutex_t _mutex; 102 #endif 103 104 void operator = (const Mutex& M); // not implemented 105 Mutex (const Mutex& M); // not implemented 106 107 friend class Lock; 108 }; 109 110 111 class Lock 112 { 113 public: 114 115 Lock (const Mutex& m, bool autoLock = true): 116 _mutex (m), 117 _locked (false) 118 { 119 if (autoLock) 120 { 121 _mutex.lock(); 122 _locked = true; 123 } 124 } 125 126 ~Lock () 127 { 128 if (_locked) 129 _mutex.unlock(); 130 } 131 132 void acquire () 133 { 134 _mutex.lock(); 135 _locked = true; 136 } 137 138 void release () 139 { 140 _mutex.unlock(); 141 _locked = false; 142 } 143 144 bool locked () 145 { 146 return _locked; 147 } 148 149 private: 150 151 const Mutex & _mutex; 152 bool _locked; 153 }; 154 155 156 } // namespace IlmThread 157 158 #endif 159