PBRT
/home/felix/UBC/projects/AdaptiveLightfieldSampling/pbrt_v2/src/3rdparty/ilmbase-1.0.2/IlmThreadMutex.h
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