Panda3D
 All Classes Functions Variables Enumerations
reMutexDirect.cxx
00001 // Filename: reMutexDirect.cxx
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 #include "reMutexDirect.h"
00016 #include "thread.h"
00017 
00018 #ifndef DEBUG_THREADS
00019 
00020 ////////////////////////////////////////////////////////////////////
00021 //     Function: ReMutexDirect::output
00022 //       Access: Published
00023 //  Description: This method is declared virtual in MutexDebug, but
00024 //               non-virtual in ReMutexDirect.
00025 ////////////////////////////////////////////////////////////////////
00026 void ReMutexDirect::
00027 output(ostream &out) const {
00028   out << "ReMutex " << (void *)this;
00029 }
00030 
00031 #ifndef HAVE_REMUTEXTRUEIMPL
00032 ////////////////////////////////////////////////////////////////////
00033 //     Function: ReMutexDirect::do_acquire
00034 //       Access: Private
00035 //  Description: The private implementation of acquire(), for the case in
00036 //               which the underlying lock system does not provide a
00037 //               reentrant mutex (and therefore we have to build this
00038 //               functionality on top of the existing non-reentrant
00039 //               mutex).
00040 ////////////////////////////////////////////////////////////////////
00041 void ReMutexDirect::
00042 do_acquire(Thread *current_thread) {
00043   _lock_impl.acquire();
00044 
00045   if (_locking_thread == (Thread *)NULL) {
00046     // The mutex is not already locked by anyone.  Lock it.
00047     _locking_thread = current_thread;
00048     ++_lock_count;
00049     nassertd(_lock_count == 1) {
00050     }
00051 
00052   } else if (_locking_thread == current_thread) {
00053     // The mutex is already locked by this thread.  Increment the lock
00054     // count.
00055     ++_lock_count;
00056     nassertd(_lock_count > 0) {
00057     }
00058     
00059   } else {
00060     // The mutex is locked by some other thread.  Go to sleep on the
00061     // condition variable until it's unlocked.
00062     while (_locking_thread != (Thread *)NULL) {
00063       _cvar_impl.wait();
00064     }
00065     
00066     _locking_thread = current_thread;
00067     ++_lock_count;
00068     nassertd(_lock_count == 1) {
00069     }
00070   }
00071   _lock_impl.release();
00072 }
00073 #endif  // !HAVE_REMUTEXTRUEIMPL
00074 
00075 #ifndef HAVE_REMUTEXTRUEIMPL
00076 ////////////////////////////////////////////////////////////////////
00077 //     Function: ReMutexDirect::do_try_acquire
00078 //       Access: Private
00079 //  Description: The private implementation of acquire(false), for the
00080 //               case in which the underlying lock system does not
00081 //               provide a reentrant mutex (and therefore we have to
00082 //               build this functionality on top of the existing
00083 //               non-reentrant mutex).
00084 ////////////////////////////////////////////////////////////////////
00085 bool ReMutexDirect::
00086 do_try_acquire(Thread *current_thread) {
00087   bool acquired = true;
00088   _lock_impl.acquire();
00089 
00090   if (_locking_thread == (Thread *)NULL) {
00091     // The mutex is not already locked by anyone.  Lock it.
00092     _locking_thread = current_thread;
00093     ++_lock_count;
00094     nassertd(_lock_count == 1) {
00095     }
00096 
00097   } else if (_locking_thread == current_thread) {
00098     // The mutex is already locked by this thread.  Increment the lock
00099     // count.
00100     ++_lock_count;
00101     nassertd(_lock_count > 0) {
00102     }
00103     
00104   } else {
00105     // The mutex is locked by some other thread.  Return false.
00106     acquired = false;
00107   }
00108   _lock_impl.release();
00109 
00110   return acquired;
00111 }
00112 #endif  // !HAVE_REMUTEXTRUEIMPL
00113 
00114 #ifndef HAVE_REMUTEXTRUEIMPL
00115 ////////////////////////////////////////////////////////////////////
00116 //     Function: ReMutexDirect::do_elevate_lock
00117 //       Access: Private
00118 //  Description: The private implementation of acquire(), for the case in
00119 //               which the underlying lock system does not provide a
00120 //               reentrant mutex (and therefore we have to build this
00121 //               functionality on top of the existing non-reentrant
00122 //               mutex).
00123 ////////////////////////////////////////////////////////////////////
00124 void ReMutexDirect::
00125 do_elevate_lock() {
00126   _lock_impl.acquire();
00127 
00128 #ifdef _DEBUG
00129   nassertd(_locking_thread == Thread::get_current_thread()) {
00130     _lock_impl.release();
00131     return;
00132   }
00133 #elif !defined(NDEBUG)
00134   nassertd(_locking_thread != (Thread *)NULL) {
00135     _lock_impl.release();
00136     return;
00137   }
00138 #endif  // NDEBUG
00139 
00140   // We know the mutex is already locked by this thread.  Increment
00141   // the lock count.
00142   ++_lock_count;
00143   nassertd(_lock_count > 0) {
00144   }
00145 
00146   _lock_impl.release();
00147 }
00148 #endif  // !HAVE_REMUTEXTRUEIMPL
00149 
00150 #ifndef HAVE_REMUTEXTRUEIMPL
00151 ////////////////////////////////////////////////////////////////////
00152 //     Function: ReMutexDirect::do_release
00153 //       Access: Private
00154 //  Description: The private implementation of release(), for the case
00155 //               in which the underlying lock system does not provide
00156 //               a reentrant mutex (and therefore we have to build
00157 //               this functionality on top of the existing
00158 //               non-reentrant mutex).
00159 ////////////////////////////////////////////////////////////////////
00160 void ReMutexDirect::
00161 do_release() {
00162   _lock_impl.acquire();
00163 
00164 #ifdef _DEBUG
00165   if (_locking_thread != Thread::get_current_thread()) {
00166     ostringstream ostr;
00167     ostr << *_locking_thread << " attempted to release "
00168          << *this << " which it does not own";
00169     nassert_raise(ostr.str());
00170     _lock_impl.release();
00171     return;
00172   }
00173 #endif  // _DEBUG
00174 
00175   nassertd(_lock_count > 0) {
00176   }
00177 
00178   --_lock_count;
00179   if (_lock_count == 0) {
00180     // That was the last lock held by this thread.  Release the lock.
00181     _locking_thread = (Thread *)NULL;
00182     _cvar_impl.notify();
00183   }
00184   _lock_impl.release();
00185 }
00186 #endif  // !HAVE_REMUTEXTRUEIMPL
00187 
00188 #endif  // !DEBUG_THREADS
 All Classes Functions Variables Enumerations