Panda3D
mutexDebug.I
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file mutexDebug.I
10  * @author drose
11  * @date 2006-02-13
12  */
13 
14 /**
15  * Alias for acquire() to match C++11 semantics.
16  * @see acquire()
17  */
18 INLINE void MutexDebug::
19 lock() {
20  TAU_PROFILE("void MutexDebug::acquire()", " ", TAU_USER);
21  _global_lock->lock();
22  ((MutexDebug *)this)->do_lock(Thread::get_current_thread());
23  _global_lock->unlock();
24 }
25 
26 /**
27  * Alias for try_acquire() to match C++11 semantics.
28  * @see try_acquire()
29  */
30 INLINE bool MutexDebug::
31 try_lock() {
32  TAU_PROFILE("void MutexDebug::try_lock()", " ", TAU_USER);
33  _global_lock->lock();
34  bool acquired = ((MutexDebug *)this)->do_try_lock(Thread::get_current_thread());
35  _global_lock->unlock();
36  return acquired;
37 }
38 
39 /**
40  * Alias for release() to match C++11 semantics.
41  * @see release()
42  */
43 INLINE void MutexDebug::
44 unlock() {
45  TAU_PROFILE("void MutexDebug::unlock()", " ", TAU_USER);
46  _global_lock->lock();
47  ((MutexDebug *)this)->do_unlock();
48  _global_lock->unlock();
49 }
50 
51 /**
52  * Grabs the mutex if it is available. If it is not available, blocks until
53  * it becomes available, then grabs it. In either case, the function does not
54  * return until the mutex is held; you should then call unlock().
55  *
56  * This method is considered const so that you can lock and unlock const
57  * mutexes, mainly to allow thread-safe access to otherwise const data.
58  *
59  * Also see MutexHolder.
60  */
61 INLINE void MutexDebug::
62 acquire(Thread *current_thread) const {
63  TAU_PROFILE("void MutexDebug::acquire(Thread *)", " ", TAU_USER);
64  nassertv(current_thread == Thread::get_current_thread());
65  _global_lock->lock();
66  ((MutexDebug *)this)->do_lock(current_thread);
67  _global_lock->unlock();
68 }
69 
70 /**
71  * Returns immediately, with a true value indicating the mutex has been
72  * acquired, and false indicating it has not.
73  */
74 INLINE bool MutexDebug::
75 try_acquire(Thread *current_thread) const {
76  TAU_PROFILE("void MutexDebug::try_acquire(Thread *)", " ", TAU_USER);
77  nassertr(current_thread == Thread::get_current_thread(), false);
78  _global_lock->lock();
79  bool acquired = ((MutexDebug *)this)->do_try_lock(current_thread);
80  _global_lock->unlock();
81  return acquired;
82 }
83 
84 /**
85  * This method increments the lock count, assuming the calling thread already
86  * holds the lock. After this call, release() will need to be called one
87  * additional time to release the lock.
88  *
89  * This method really performs the same function as acquire(), but it offers a
90  * potential (slight) performance benefit when the calling thread knows that
91  * it already holds the lock. It is an error to call this when the calling
92  * thread does not hold the lock.
93  */
94 INLINE void MutexDebug::
95 elevate_lock() const {
96  TAU_PROFILE("void MutexDebug::elevate_lock()", " ", TAU_USER);
97  // You may only pass call elevate_lock() on a ReMutex--that is, to a mutex
98  // whose _allow_recursion flag is true.
99  nassertv(_allow_recursion);
100 
101  // Also, it's an error to call this if the lock is not already held.
102  nassertv(debug_is_locked());
103 
104  acquire();
105 }
106 
107 /**
108  * Releases the mutex. It is an error to call this if the mutex was not
109  * already locked.
110  *
111  * This method is considered const so that you can lock and unlock const
112  * mutexes, mainly to allow thread-safe access to otherwise const data.
113  */
114 INLINE void MutexDebug::
115 release() const {
116  TAU_PROFILE("void MutexDebug::release()", " ", TAU_USER);
117  _global_lock->lock();
118  ((MutexDebug *)this)->do_unlock();
119  _global_lock->unlock();
120 }
121 
122 /**
123  * Returns true if the current thread has locked the Mutex, false otherwise.
124  * This method is only intended for use in debugging, hence the method name;
125  * in the MutexDebug case, it always returns true, since there's not a
126  * reliable way to determine this otherwise.
127  */
128 INLINE bool MutexDebug::
129 debug_is_locked() const {
130  TAU_PROFILE("bool MutexDebug::debug_is_locked()", " ", TAU_USER);
131  _global_lock->lock();
132  bool is_locked = do_debug_is_locked();
133  _global_lock->unlock();
134  return is_locked;
135 }
136 
137 /**
138  * Ensures the global MutexImpl pointer has been created, and returns its
139  * pointer. Since this method is called by the MutexDebug constructor, any
140  * other (non-static) methods of MutexDebug may simply assume that the pointer
141  * has already been created.
142  */
143 INLINE MutexTrueImpl *MutexDebug::
144 get_global_lock() {
145  if (_global_lock == nullptr) {
146  _global_lock = new MutexTrueImpl;
147  }
148  return _global_lock;
149 }
A thread; that is, a lightweight process.
Definition: thread.h:46
A fake mutex implementation for single-threaded applications that don't need any synchronization cont...