Panda3D
Loading...
Searching...
No Matches
reMutexDirect.cxx
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 reMutexDirect.cxx
10 * @author drose
11 * @date 2006-02-13
12 */
13
14#include "reMutexDirect.h"
15#include "thread.h"
16
17#ifndef DEBUG_THREADS
18
19/**
20 * This method is declared virtual in MutexDebug, but non-virtual in
21 * ReMutexDirect.
22 */
24output(std::ostream &out) const {
25 out << "ReMutex " << (void *)this;
26}
27
28#ifndef HAVE_REMUTEXTRUEIMPL
29/**
30 * The private implementation of acquire(), for the case in which the
31 * underlying lock system does not provide a reentrant mutex (and therefore we
32 * have to build this functionality on top of the existing non-reentrant
33 * mutex).
34 */
35void ReMutexDirect::
36do_lock(Thread *current_thread) {
37 _lock_impl.lock();
38
39 if (_locking_thread == nullptr) {
40 // The mutex is not already locked by anyone. Lock it.
41 _locking_thread = current_thread;
42 ++_lock_count;
43 nassertd(_lock_count == 1) {
44 }
45
46 } else if (_locking_thread == current_thread) {
47 // The mutex is already locked by this thread. Increment the lock count.
48 ++_lock_count;
49 nassertd(_lock_count > 0) {
50 }
51
52 } else {
53 // The mutex is locked by some other thread. Go to sleep on the condition
54 // variable until it's unlocked.
55 while (_locking_thread != nullptr) {
56 _cvar_impl.wait();
57 }
58
59 _locking_thread = current_thread;
60 ++_lock_count;
61 nassertd(_lock_count == 1) {
62 }
63 }
64 _lock_impl.unlock();
65}
66#endif // !HAVE_REMUTEXTRUEIMPL
67
68#ifndef HAVE_REMUTEXTRUEIMPL
69/**
70 * The private implementation of acquire(false), for the case in which the
71 * underlying lock system does not provide a reentrant mutex (and therefore we
72 * have to build this functionality on top of the existing non-reentrant
73 * mutex).
74 */
75bool ReMutexDirect::
76do_try_lock(Thread *current_thread) {
77 bool acquired = true;
78 _lock_impl.lock();
79
80 if (_locking_thread == nullptr) {
81 // The mutex is not already locked by anyone. Lock it.
82 _locking_thread = current_thread;
83 ++_lock_count;
84 nassertd(_lock_count == 1) {
85 }
86
87 } else if (_locking_thread == current_thread) {
88 // The mutex is already locked by this thread. Increment the lock count.
89 ++_lock_count;
90 nassertd(_lock_count > 0) {
91 }
92
93 } else {
94 // The mutex is locked by some other thread. Return false.
95 acquired = false;
96 }
97 _lock_impl.unlock();
98
99 return acquired;
100}
101#endif // !HAVE_REMUTEXTRUEIMPL
102
103#ifndef HAVE_REMUTEXTRUEIMPL
104/**
105 * The private implementation of acquire(), for the case in which the
106 * underlying lock system does not provide a reentrant mutex (and therefore we
107 * have to build this functionality on top of the existing non-reentrant
108 * mutex).
109 */
110void ReMutexDirect::
111do_elevate_lock() {
112 _lock_impl.lock();
113
114#ifdef _DEBUG
115 nassertd(_locking_thread == Thread::get_current_thread()) {
116 _lock_impl.unlock();
117 return;
118 }
119#elif !defined(NDEBUG)
120 nassertd(_locking_thread != nullptr) {
121 _lock_impl.unlock();
122 return;
123 }
124#endif // NDEBUG
125
126 // We know the mutex is already locked by this thread. Increment the lock
127 // count.
128 ++_lock_count;
129 nassertd(_lock_count > 0) {
130 }
131
132 _lock_impl.unlock();
133}
134#endif // !HAVE_REMUTEXTRUEIMPL
135
136#ifndef HAVE_REMUTEXTRUEIMPL
137/**
138 * The private implementation of release(), for the case in which the
139 * underlying lock system does not provide a reentrant mutex (and therefore we
140 * have to build this functionality on top of the existing non-reentrant
141 * mutex).
142 */
143void ReMutexDirect::
144do_unlock(Thread *current_thread) {
145 _lock_impl.lock();
146
147#ifdef _DEBUG
148 if (_locking_thread != current_thread) {
149 std::ostringstream ostr;
150 ostr << *_locking_thread << " attempted to release "
151 << *this << " which it does not own";
152 nassert_raise(ostr.str());
153 _lock_impl.unlock();
154 return;
155 }
156#endif // _DEBUG
157
158 nassertd(_lock_count > 0) {
159 }
160
161 --_lock_count;
162 if (_lock_count == 0) {
163 // That was the last lock held by this thread. Release the lock.
164 _locking_thread = nullptr;
165 _cvar_impl.notify();
166 }
167 _lock_impl.unlock();
168}
169#endif // !HAVE_REMUTEXTRUEIMPL
170
171#endif // !DEBUG_THREADS
void output(std::ostream &out) const
This method is declared virtual in MutexDebug, but non-virtual in ReMutexDirect.
A thread; that is, a lightweight process.
Definition thread.h:46
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition thread.h:109
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.