Panda3D
|
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 ©) : _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 ©) { 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 }