| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- /**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University. All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license. You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file reMutexDirect.cxx
- * @author drose
- * @date 2006-02-13
- */
- #include "reMutexDirect.h"
- #include "thread.h"
- #ifndef DEBUG_THREADS
- /**
- * This method is declared virtual in MutexDebug, but non-virtual in
- * ReMutexDirect.
- */
- void ReMutexDirect::
- output(std::ostream &out) const {
- out << "ReMutex " << (void *)this;
- }
- #ifndef HAVE_REMUTEXTRUEIMPL
- /**
- * The private implementation of acquire(), for the case in which the
- * underlying lock system does not provide a reentrant mutex (and therefore we
- * have to build this functionality on top of the existing non-reentrant
- * mutex).
- */
- void ReMutexDirect::
- do_lock(Thread *current_thread) {
- _lock_impl.lock();
- if (_locking_thread == nullptr) {
- // The mutex is not already locked by anyone. Lock it.
- _locking_thread = current_thread;
- ++_lock_count;
- nassertd(_lock_count == 1) {
- }
- } else if (_locking_thread == current_thread) {
- // The mutex is already locked by this thread. Increment the lock count.
- ++_lock_count;
- nassertd(_lock_count > 0) {
- }
- } else {
- // The mutex is locked by some other thread. Go to sleep on the condition
- // variable until it's unlocked.
- while (_locking_thread != nullptr) {
- _cvar_impl.wait();
- }
- _locking_thread = current_thread;
- ++_lock_count;
- nassertd(_lock_count == 1) {
- }
- }
- _lock_impl.unlock();
- }
- #endif // !HAVE_REMUTEXTRUEIMPL
- #ifndef HAVE_REMUTEXTRUEIMPL
- /**
- * The private implementation of acquire(false), for the case in which the
- * underlying lock system does not provide a reentrant mutex (and therefore we
- * have to build this functionality on top of the existing non-reentrant
- * mutex).
- */
- bool ReMutexDirect::
- do_try_lock(Thread *current_thread) {
- bool acquired = true;
- _lock_impl.lock();
- if (_locking_thread == nullptr) {
- // The mutex is not already locked by anyone. Lock it.
- _locking_thread = current_thread;
- ++_lock_count;
- nassertd(_lock_count == 1) {
- }
- } else if (_locking_thread == current_thread) {
- // The mutex is already locked by this thread. Increment the lock count.
- ++_lock_count;
- nassertd(_lock_count > 0) {
- }
- } else {
- // The mutex is locked by some other thread. Return false.
- acquired = false;
- }
- _lock_impl.unlock();
- return acquired;
- }
- #endif // !HAVE_REMUTEXTRUEIMPL
- #ifndef HAVE_REMUTEXTRUEIMPL
- /**
- * The private implementation of acquire(), for the case in which the
- * underlying lock system does not provide a reentrant mutex (and therefore we
- * have to build this functionality on top of the existing non-reentrant
- * mutex).
- */
- void ReMutexDirect::
- do_elevate_lock() {
- _lock_impl.lock();
- #ifdef _DEBUG
- nassertd(_locking_thread == Thread::get_current_thread()) {
- _lock_impl.unlock();
- return;
- }
- #elif !defined(NDEBUG)
- nassertd(_locking_thread != nullptr) {
- _lock_impl.unlock();
- return;
- }
- #endif // NDEBUG
- // We know the mutex is already locked by this thread. Increment the lock
- // count.
- ++_lock_count;
- nassertd(_lock_count > 0) {
- }
- _lock_impl.unlock();
- }
- #endif // !HAVE_REMUTEXTRUEIMPL
- #ifndef HAVE_REMUTEXTRUEIMPL
- /**
- * The private implementation of release(), for the case in which the
- * underlying lock system does not provide a reentrant mutex (and therefore we
- * have to build this functionality on top of the existing non-reentrant
- * mutex).
- */
- void ReMutexDirect::
- do_unlock(Thread *current_thread) {
- _lock_impl.lock();
- #ifdef _DEBUG
- if (_locking_thread != current_thread) {
- std::ostringstream ostr;
- ostr << *_locking_thread << " attempted to release "
- << *this << " which it does not own";
- nassert_raise(ostr.str());
- _lock_impl.unlock();
- return;
- }
- #endif // _DEBUG
- nassertd(_lock_count > 0) {
- }
- --_lock_count;
- if (_lock_count == 0) {
- // That was the last lock held by this thread. Release the lock.
- _locking_thread = nullptr;
- _cvar_impl.notify();
- }
- _lock_impl.unlock();
- }
- #endif // !HAVE_REMUTEXTRUEIMPL
- #endif // !DEBUG_THREADS
|