PBRT
|
00001 00002 // 00003 // Copyright (c) 2005, Industrial Light & Magic, a division of Lucas 00004 // Digital Ltd. LLC 00005 // 00006 // All rights reserved. 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are 00010 // met: 00011 // * Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // * Redistributions in binary form must reproduce the above 00014 // copyright notice, this list of conditions and the following disclaimer 00015 // in the documentation and/or other materials provided with the 00016 // distribution. 00017 // * Neither the name of Industrial Light & Magic nor the names of 00018 // its contributors may be used to endorse or promote products derived 00019 // from this software without specific prior written permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00034 00035 #ifndef INCLUDED_ILM_THREAD_MUTEX_H 00036 #define INCLUDED_ILM_THREAD_MUTEX_H 00037 00038 //----------------------------------------------------------------------------- 00039 // 00040 // class Mutex, class Lock 00041 // 00042 // Class Mutex is a wrapper for a system-dependent mutual exclusion 00043 // mechanism. Actual locking and unlocking of a Mutex object must 00044 // be performed using an instance of a Lock (defined below). 00045 // 00046 // Class lock provides safe locking and unlocking of mutexes even in 00047 // the presence of C++ exceptions. Constructing a Lock object locks 00048 // the mutex; destroying the Lock unlocks the mutex. 00049 // 00050 // Lock objects are not themselves thread-safe. You should never 00051 // share a Lock object among multiple threads. 00052 // 00053 // Typical usage: 00054 // 00055 // Mutex mtx; // Create a Mutex object that is visible 00056 // //to multiple threads 00057 // 00058 // ... // create some threads 00059 // 00060 // // Then, within each thread, construct a critical section like so: 00061 // 00062 // { 00063 // Lock lock (mtx); // Lock constructor locks the mutex 00064 // ... // do some computation on shared data 00065 // } // leaving the block unlocks the mutex 00066 // 00067 //----------------------------------------------------------------------------- 00068 00069 #include "IlmBaseConfig.h" 00070 00071 #if defined _WIN32 || defined _WIN64 00072 #ifdef NOMINMAX 00073 #undef NOMINMAX 00074 #endif 00075 #define NOMINMAX 00076 #include <windows.h> 00077 #elif HAVE_PTHREAD 00078 #include <pthread.h> 00079 #endif 00080 00081 namespace IlmThread { 00082 00083 class Lock; 00084 00085 00086 class Mutex 00087 { 00088 public: 00089 00090 Mutex (); 00091 virtual ~Mutex (); 00092 00093 private: 00094 00095 void lock () const; 00096 void unlock () const; 00097 00098 #if defined _WIN32 || defined _WIN64 00099 mutable CRITICAL_SECTION _mutex; 00100 #elif HAVE_PTHREAD 00101 mutable pthread_mutex_t _mutex; 00102 #endif 00103 00104 void operator = (const Mutex& M); // not implemented 00105 Mutex (const Mutex& M); // not implemented 00106 00107 friend class Lock; 00108 }; 00109 00110 00111 class Lock 00112 { 00113 public: 00114 00115 Lock (const Mutex& m, bool autoLock = true): 00116 _mutex (m), 00117 _locked (false) 00118 { 00119 if (autoLock) 00120 { 00121 _mutex.lock(); 00122 _locked = true; 00123 } 00124 } 00125 00126 ~Lock () 00127 { 00128 if (_locked) 00129 _mutex.unlock(); 00130 } 00131 00132 void acquire () 00133 { 00134 _mutex.lock(); 00135 _locked = true; 00136 } 00137 00138 void release () 00139 { 00140 _mutex.unlock(); 00141 _locked = false; 00142 } 00143 00144 bool locked () 00145 { 00146 return _locked; 00147 } 00148 00149 private: 00150 00151 const Mutex & _mutex; 00152 bool _locked; 00153 }; 00154 00155 00156 } // namespace IlmThread 00157 00158 #endif