Panda3D

mutexDebug.I

00001 // Filename: mutexDebug.I
00002 // Created by:  drose (13Feb06)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 
00016 ////////////////////////////////////////////////////////////////////
00017 //     Function: MutexDebug::Copy Constructor
00018 //       Access: Private
00019 //  Description: Do not attempt to copy mutexes.
00020 ////////////////////////////////////////////////////////////////////
00021 INLINE MutexDebug::
00022 MutexDebug(const MutexDebug &copy) : _cvar_impl(*get_global_lock()) {
00023   nassertv(false);
00024 }
00025 
00026 ////////////////////////////////////////////////////////////////////
00027 //     Function: MutexDebug::Copy Assignment Operator
00028 //       Access: Private
00029 //  Description: Do not attempt to copy mutexes.
00030 ////////////////////////////////////////////////////////////////////
00031 INLINE void MutexDebug::
00032 operator = (const MutexDebug &copy) {
00033   nassertv(false);
00034 }
00035 
00036 ////////////////////////////////////////////////////////////////////
00037 //     Function: MutexDebug::acquire
00038 //       Access: Published
00039 //  Description: Grabs the mutex if it is available.  If it is not
00040 //               available, blocks until it becomes available, then
00041 //               grabs it.  In either case, the function does not
00042 //               return until the mutex is held; you should then call
00043 //               unlock().
00044 //
00045 //               This method is considered const so that you can lock
00046 //               and unlock const mutexes, mainly to allow thread-safe
00047 //               access to otherwise const data.
00048 //
00049 //               Also see MutexHolder.
00050 ////////////////////////////////////////////////////////////////////
00051 INLINE void MutexDebug::
00052 acquire(Thread *current_thread) const {
00053   TAU_PROFILE("void MutexDebug::acquire(Thread *)", " ", TAU_USER);
00054   nassertv(current_thread == Thread::get_current_thread());
00055   _global_lock->acquire();
00056   ((MutexDebug *)this)->do_acquire(current_thread);
00057   _global_lock->release();
00058 }
00059 
00060 ////////////////////////////////////////////////////////////////////
00061 //     Function: MutexDebug::try_acquire
00062 //       Access: Published
00063 //  Description: Returns immediately, with a true value indicating the
00064 //               mutex has been acquired, and false indicating it has
00065 //               not.
00066 ////////////////////////////////////////////////////////////////////
00067 INLINE bool MutexDebug::
00068 try_acquire(Thread *current_thread) const {
00069   TAU_PROFILE("void MutexDebug::acquire(Thread *)", " ", TAU_USER);
00070   nassertr(current_thread == Thread::get_current_thread(), false);
00071   _global_lock->acquire();
00072   bool acquired = ((MutexDebug *)this)->do_try_acquire(current_thread);
00073   _global_lock->release();
00074   return acquired;
00075 }
00076 
00077 ////////////////////////////////////////////////////////////////////
00078 //     Function: MutexDebug::elevate_lock
00079 //       Access: Published
00080 //  Description: This method increments the lock count, assuming the
00081 //               calling thread already holds the lock.  After this
00082 //               call, release() will need to be called one additional
00083 //               time to release the lock.
00084 //
00085 //               This method really performs the same function as
00086 //               acquire(), but it offers a potential (slight)
00087 //               performance benefit when the calling thread knows
00088 //               that it already holds the lock.  It is an error to
00089 //               call this when the calling thread does not hold the
00090 //               lock.
00091 ////////////////////////////////////////////////////////////////////
00092 INLINE void MutexDebug::
00093 elevate_lock() const {
00094   TAU_PROFILE("void MutexDebug::elevate_lock()", " ", TAU_USER);
00095   // You may only pass call elevate_lock() on a ReMutex--that is, to a
00096   // mutex whose _allow_recursion flag is true.
00097   nassertv(_allow_recursion);
00098 
00099   // Also, it's an error to call this if the lock is not already held.
00100   nassertv(debug_is_locked());
00101 
00102   acquire();
00103 }
00104 
00105 ////////////////////////////////////////////////////////////////////
00106 //     Function: MutexDebug::release
00107 //       Access: Published
00108 //  Description: Releases the mutex.  It is an error to call this if
00109 //               the mutex was not already locked.
00110 //
00111 //               This method is considered const so that you can lock
00112 //               and unlock const mutexes, mainly to allow thread-safe
00113 //               access to otherwise const data.
00114 ////////////////////////////////////////////////////////////////////
00115 INLINE void MutexDebug::
00116 release() const {
00117   TAU_PROFILE("void MutexDebug::release()", " ", TAU_USER);
00118   _global_lock->acquire();
00119   ((MutexDebug *)this)->do_release();
00120   _global_lock->release();
00121 }
00122 
00123 ////////////////////////////////////////////////////////////////////
00124 //     Function: MutexDebug::debug_is_locked
00125 //       Access: Published
00126 //  Description: Returns true if the current thread has locked the
00127 //               Mutex, false otherwise.  This method is only intended
00128 //               for use in debugging, hence the method name; in the
00129 //               MutexDebug case, it always returns true, since
00130 //               there's not a reliable way to determine this
00131 //               otherwise.
00132 ////////////////////////////////////////////////////////////////////
00133 INLINE bool MutexDebug::
00134 debug_is_locked() const {
00135   TAU_PROFILE("bool MutexDebug::debug_is_locked()", " ", TAU_USER);
00136   _global_lock->acquire();
00137   bool is_locked = do_debug_is_locked();
00138   _global_lock->release();
00139   return is_locked;
00140 }
00141 
00142 ////////////////////////////////////////////////////////////////////
00143 //     Function: MutexDebug::get_global_lock
00144 //       Access: Private, Static
00145 //  Description: Ensures the global MutexImpl pointer has been
00146 //               created, and returns its pointer.  Since this method
00147 //               is called by the MutexDebug constructor, any other
00148 //               (non-static) methods of MutexDebug may simply assume
00149 //               that the pointer has already been created.
00150 ////////////////////////////////////////////////////////////////////
00151 INLINE MutexTrueImpl *MutexDebug::
00152 get_global_lock() {
00153   if (_global_lock == (MutexTrueImpl *)NULL) {
00154     _global_lock = new MutexTrueImpl;
00155   }
00156   return _global_lock;
00157 }
 All Classes Functions Variables Enumerations