瀏覽代碼

ConditionVarFull

David Rose 19 年之前
父節點
當前提交
01a09a9d28
共有 34 個文件被更改,包括 937 次插入527 次删除
  1. 1 0
      dtool/src/dtoolbase/mutexWin32Impl.h
  2. 12 6
      panda/src/pipeline/Sources.pp
  3. 6 0
      panda/src/pipeline/conditionVar.h
  4. 2 1
      panda/src/pipeline/conditionVarDebug.cxx
  5. 2 1
      panda/src/pipeline/conditionVarDirect.I
  6. 88 0
      panda/src/pipeline/conditionVarFull.I
  7. 19 0
      panda/src/pipeline/conditionVarFull.cxx
  8. 73 0
      panda/src/pipeline/conditionVarFull.h
  9. 23 37
      panda/src/pipeline/conditionVarFullDebug.I
  10. 191 0
      panda/src/pipeline/conditionVarFullDebug.cxx
  11. 71 0
      panda/src/pipeline/conditionVarFullDebug.h
  12. 152 0
      panda/src/pipeline/conditionVarFullDirect.I
  13. 12 17
      panda/src/pipeline/conditionVarFullDirect.cxx
  14. 71 0
      panda/src/pipeline/conditionVarFullDirect.h
  15. 77 0
      panda/src/pipeline/conditionVarFullWin32Impl.I
  16. 25 0
      panda/src/pipeline/conditionVarFullWin32Impl.cxx
  17. 65 0
      panda/src/pipeline/conditionVarFullWin32Impl.h
  18. 6 5
      panda/src/pipeline/conditionVarImpl.h
  19. 0 55
      panda/src/pipeline/conditionVarLinuxImpl.cxx
  20. 0 53
      panda/src/pipeline/conditionVarLinuxImpl.h
  21. 11 0
      panda/src/pipeline/conditionVarNsprImpl.I
  22. 1 0
      panda/src/pipeline/conditionVarNsprImpl.h
  23. 12 0
      panda/src/pipeline/conditionVarPosixImpl.I
  24. 1 0
      panda/src/pipeline/conditionVarPosixImpl.h
  25. 10 0
      panda/src/pipeline/conditionVarSpinlockImpl.I
  26. 1 0
      panda/src/pipeline/conditionVarSpinlockImpl.h
  27. 1 0
      panda/src/pipeline/mutexDebug.h
  28. 1 0
      panda/src/pipeline/mutexDirect.h
  29. 3 1
      panda/src/pipeline/pipeline_composite1.cxx
  30. 0 1
      panda/src/pipeline/pipeline_composite2.cxx
  31. 0 1
      panda/src/pipeline/thread.h
  32. 0 5
      panda/src/pipeline/threadImpl.h
  33. 0 260
      panda/src/pipeline/threadLinuxImpl.cxx
  34. 0 84
      panda/src/pipeline/threadLinuxImpl.h

+ 1 - 0
dtool/src/dtoolbase/mutexWin32Impl.h

@@ -42,6 +42,7 @@ public:
 private:
   CRITICAL_SECTION _lock;
   friend class ConditionVarWin32Impl;
+  friend class ConditionVarFullWin32Impl;
 };
 
 #include "mutexWin32Impl.I"

+ 12 - 6
panda/src/pipeline/Sources.pp

@@ -14,9 +14,12 @@
     conditionVarDebug.h conditionVarDebug.I \
     conditionVarDirect.h conditionVarDirect.I \
     conditionVarDummyImpl.h conditionVarDummyImpl.I \
+    conditionVarFull.h conditionVarFull.I \
+    conditionVarFullDebug.h conditionVarFullDebug.I \
+    conditionVarFullDirect.h conditionVarFullDirect.I \
+    conditionVarFullWin32Impl.h conditionVarFullWin32Impl.I \
     conditionVarImpl.h \
     conditionVarNsprImpl.h conditionVarNsprImpl.I \
-    conditionVarLinuxImpl.h conditionVarLinuxImpl.I \
     conditionVarPosixImpl.h conditionVarPosixImpl.I \
     conditionVarWin32Impl.h conditionVarWin32Impl.I \
     conditionVarSpinlockImpl.h conditionVarSpinlockImpl.I \
@@ -47,7 +50,6 @@
     reMutexHolder.I reMutexHolder.h \
     threadDummyImpl.h threadDummyImpl.I thread.h thread.I threadImpl.h \
     threadNsprImpl.h threadNsprImpl.I \
-    threadLinuxImpl.h threadLinuxImpl.I \
     threadPosixImpl.h threadPosixImpl.I \
     threadWin32Impl.h threadWin32Impl.I \
     threadPriority.h
@@ -57,8 +59,11 @@
     conditionVarDebug.cxx \
     conditionVarDirect.cxx \
     conditionVarDummyImpl.cxx \
+    conditionVarFull.cxx \
+    conditionVarFullDebug.cxx \
+    conditionVarFullDirect.cxx \
+    conditionVarFullWin32Impl.cxx \
     conditionVarNsprImpl.cxx \
-    conditionVarLinuxImpl.cxx \
     conditionVarPosixImpl.cxx \
     conditionVarWin32Impl.cxx \
     conditionVarSpinlockImpl.cxx \
@@ -87,7 +92,6 @@
     reMutexHolder.cxx \
     thread.cxx threadDummyImpl.cxx \
     threadNsprImpl.cxx \
-    threadLinuxImpl.cxx \
     threadPosixImpl.cxx \
     threadWin32Impl.cxx
 
@@ -96,9 +100,12 @@
     conditionVarDebug.h conditionVarDebug.I \
     conditionVarDirect.h conditionVarDirect.I \
     conditionVarDummyImpl.h conditionVarDummyImpl.I \
+    conditionVarFull.h conditionVarFull.I \
+    conditionVarFullDebug.h conditionVarFullDebug.I \
+    conditionVarFullDirect.h conditionVarFullDirect.I \
+    conditionVarFullWin32Impl.h conditionVarFullWin32Impl.I \
     conditionVarImpl.h \
     conditionVarNsprImpl.h conditionVarNsprImpl.I \
-    conditionVarLinuxImpl.h conditionVarLinuxImpl.I \
     conditionVarPosixImpl.h conditionVarPosixImpl.I \
     conditionVarWin32Impl.h conditionVarWin32Impl.I \
     conditionVarSpinlockImpl.h conditionVarSpinlockImpl.I \
@@ -129,7 +136,6 @@
     reMutexHolder.I reMutexHolder.h \
     threadDummyImpl.h threadDummyImpl.I thread.h thread.I threadImpl.h \
     threadNsprImpl.h threadNsprImpl.I \
-    threadLinuxImpl.h threadLinuxImpl.I \
     threadPosixImpl.h threadPosixImpl.I \
     threadWin32Impl.h threadWin32Impl.I \
     threadPriority.h

+ 6 - 0
panda/src/pipeline/conditionVar.h

@@ -30,6 +30,12 @@
 //               waiting for something to happen.  A condition
 //               variable can be used to "wake up" a thread when some
 //               arbitrary condition has changed.
+
+//               The ConditionVar class does not support the full
+//               semantics of POSIX condition variables.  In
+//               particular, it does not support the broadcast or
+//               signal_all function.  See ConditionVarFull for a more
+//               complete (but possibly more expensive) API.
 //
 //               A condition variable is associated with a single
 //               mutex, and several condition variables may share the

+ 2 - 1
panda/src/pipeline/conditionVarDebug.cxx

@@ -111,7 +111,8 @@ wait() {
 //               blocked on wait() that the relevant condition has
 //               changed.  If multiple threads are currently waiting,
 //               at least one of them will be woken up, although there
-//               is no way to predict which one.
+//               is no way to predict which one.  It is possible that
+//               more than one thread will be woken up.
 //
 //               The caller must be holding the mutex associated with
 //               the condition variable before making this call, which

+ 2 - 1
panda/src/pipeline/conditionVarDirect.I

@@ -115,7 +115,8 @@ wait() {
 //               blocked on wait() that the relevant condition has
 //               changed.  If multiple threads are currently waiting,
 //               at least one of them will be woken up, although there
-//               is no way to predict which one.
+//               is no way to predict which one.  It is possible that
+//               more than one thread will be woken up.
 //
 //               The caller must be holding the mutex associated with
 //               the condition variable before making this call, which

+ 88 - 0
panda/src/pipeline/conditionVarFull.I

@@ -0,0 +1,88 @@
+// Filename: conditionVarFull.I
+// Created by:  drose (28Aug06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFull::Constructor
+//       Access: Public
+//  Description: You must pass in a Mutex to the condition variable
+//               constructor.  This mutex may be shared by other
+//               condition variables, if desired.  It is the caller's
+//               responsibility to ensure the Mutex object does not
+//               destruct during the lifetime of the condition
+//               variable.
+////////////////////////////////////////////////////////////////////
+INLINE ConditionVarFull::
+ConditionVarFull(Mutex &mutex) :
+#ifdef DEBUG_THREADS
+  ConditionVarFullDebug(mutex)
+#else 
+  ConditionVarFullDirect(mutex)
+#endif  // DEBUG_THREADS
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFull::Destructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE ConditionVarFull::
+~ConditionVarFull() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFull::Copy Constructor
+//       Access: Private
+//  Description: Do not attempt to copy condition variables.
+////////////////////////////////////////////////////////////////////
+INLINE ConditionVarFull::
+ConditionVarFull(const ConditionVarFull &copy) : 
+#ifdef DEBUG_THREADS
+  ConditionVarFullDebug(copy.get_mutex())
+#else 
+  ConditionVarFullDirect(copy.get_mutex())
+#endif  // DEBUG_THREADS
+{
+  nassertv(false);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFull::Copy Assignment Operator
+//       Access: Private
+//  Description: Do not attempt to copy condition variables.
+////////////////////////////////////////////////////////////////////
+INLINE void ConditionVarFull::
+operator = (const ConditionVarFull &copy) {
+  nassertv(false);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFull::get_mutex
+//       Access: Public
+//  Description: Returns the mutex associated with this condition
+//               variable.
+////////////////////////////////////////////////////////////////////
+INLINE Mutex &ConditionVarFull::
+get_mutex() const {
+#ifdef DEBUG_THREADS
+  return (Mutex &)ConditionVarFullDebug::get_mutex();
+#else 
+  return (Mutex &)ConditionVarFullDirect::get_mutex();
+#endif  // DEBUG_THREADS
+}

+ 19 - 0
panda/src/pipeline/conditionVarFull.cxx

@@ -0,0 +1,19 @@
+// Filename: conditionVarFull.cxx
+// Created by:  drose (28Aug06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "conditionVarFull.h"

+ 73 - 0
panda/src/pipeline/conditionVarFull.h

@@ -0,0 +1,73 @@
+// Filename: conditionVarFull.h
+// Created by:  drose (28Aug06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef CONDITIONVARFULL_H
+#define CONDITIONVARFULL_H
+
+#include "pandabase.h"
+#include "conditionVarFullDebug.h"
+#include "conditionVarFullDirect.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : ConditionVarFull
+// Description : This class implements a condition variable; see
+//               ConditionVar for a brief introduction to this class.
+//               The ConditionVarFull class provides a more complete
+//               implementation than ConditionVar; in particular, it
+//               provides the signal_all() method, which is guaranteed
+//               to wake up all threads currently waiting on the
+//               condition (whereas signal() is guaranteed to wake up
+//               at least one thread, but may or may not wake up all
+//               of them).
+//
+//               This class exists because on certain platforms
+//               (e.g. Win32), implementing signal_all() requires more
+//               overhead, so you should use ConditionVar for cases
+//               when you do not require the signal_all() semantics.
+//
+//               There are still some minor semantics that POSIX
+//               condition variables provide which this implementation
+//               does not.  For instance, it is required (not
+//               optional) that the caller of signal() or signal_all()
+//               is holding the condition variable's mutex before the
+//               call.
+//
+//               This class inherits its implementation either from
+//               ConditionVarFullDebug or ConditionVarFullDirect,
+//               depending on the definition of DEBUG_THREADS.
+////////////////////////////////////////////////////////////////////
+#ifdef DEBUG_THREADS
+class EXPCL_PANDA ConditionVarFull : public ConditionVarFullDebug
+#else
+class EXPCL_PANDA ConditionVarFull : public ConditionVarFullDirect
+#endif  // DEBUG_THREADS
+{
+public:
+  INLINE ConditionVarFull(Mutex &mutex);
+  INLINE ~ConditionVarFull();
+private:
+  INLINE ConditionVarFull(const ConditionVarFull &copy);
+  INLINE void operator = (const ConditionVarFull &copy);
+
+public:
+  INLINE Mutex &get_mutex() const;
+};
+
+#include "conditionVarFull.I"
+
+#endif

+ 23 - 37
panda/src/pipeline/threadLinuxImpl.I → panda/src/pipeline/conditionVarFullDebug.I

@@ -1,5 +1,5 @@
-// Filename: threadLinuxImpl.I
-// Created by:  drose (28Mar06)
+// Filename: conditionVarFullDebug.I
+// Created by:  drose (28Aug06)
 //
 ////////////////////////////////////////////////////////////////////
 //
@@ -18,49 +18,35 @@
 
 
 ////////////////////////////////////////////////////////////////////
-//     Function: ThreadLinuxImpl::Constructor
-//       Access: Public
-//  Description: 
+//     Function: ConditionVarFullDebug::Copy Constructor
+//       Access: Private
+//  Description: Do not attempt to copy condition variables.
 ////////////////////////////////////////////////////////////////////
-INLINE ThreadLinuxImpl::
-ThreadLinuxImpl(Thread *parent_obj) :
-  _cv(_mutex),
-  _parent_obj(parent_obj)
+INLINE ConditionVarFullDebug::
+ConditionVarFullDebug(const ConditionVarFullDebug &copy) : 
+  _mutex(copy._mutex), 
+  _impl(*_mutex._global_lock)
 {
-  _thread = 0;
-  _joinable = false;
-  _status = S_new;
-  _stack = NULL;
+  nassertv(false);
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: ThreadLinuxImpl::prepare_for_exit
-//       Access: Public
-//  Description: 
+//     Function: ConditionVarFullDebug::Copy Assignment Operator
+//       Access: Private
+//  Description: Do not attempt to copy condition variables.
 ////////////////////////////////////////////////////////////////////
-INLINE void ThreadLinuxImpl::
-prepare_for_exit() {
+INLINE void ConditionVarFullDebug::
+operator = (const ConditionVarFullDebug &copy) {
+  nassertv(false);
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: ThreadLinuxImpl::is_threading_supported
-//       Access: Public, Static
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE bool ThreadLinuxImpl::
-is_threading_supported() {
-  return true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ThreadLinuxImpl::sleep
-//       Access: Public, Static
-//  Description: 
+//     Function: ConditionVarFullDebug::get_mutex
+//       Access: Public
+//  Description: Returns the mutex associated with this condition
+//               variable.
 ////////////////////////////////////////////////////////////////////
-INLINE void ThreadLinuxImpl::
-sleep(double seconds) {
-  struct timespec rqtp;
-  rqtp.tv_sec = time_t(seconds);
-  rqtp.tv_nsec = long((seconds - (double)rqtp.tv_sec) * 1000000000.0);
-  nanosleep(&rqtp, NULL);
+INLINE MutexDebug &ConditionVarFullDebug::
+get_mutex() const {
+  return _mutex;
 }

+ 191 - 0
panda/src/pipeline/conditionVarFullDebug.cxx

@@ -0,0 +1,191 @@
+// Filename: conditionVarFullDebug.cxx
+// Created by:  drose (28Aug06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "conditionVarFullDebug.h"
+#include "thread.h"
+#include "config_pipeline.h"
+
+#ifdef DEBUG_THREADS
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullDebug::Constructor
+//       Access: Public
+//  Description: You must pass in a Mutex to the condition variable
+//               constructor.  This mutex may be shared by other
+//               condition variables, if desired.  It is the caller's
+//               responsibility to ensure the Mutex object does not
+//               destruct during the lifetime of the condition
+//               variable.
+////////////////////////////////////////////////////////////////////
+ConditionVarFullDebug::
+ConditionVarFullDebug(MutexDebug &mutex) :
+  _mutex(mutex),
+  _impl(*mutex.get_global_lock())
+{
+  nassertv(!_mutex._allow_recursion);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullDebug::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+ConditionVarFullDebug::
+~ConditionVarFullDebug() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullDebug::wait
+//       Access: Public
+//  Description: Waits on the condition.  The caller must already be
+//               holding the lock associated with the condition
+//               variable before calling this function.
+//
+//               wait() will release the lock, then go to sleep until
+//               some other thread calls signal() on this condition
+//               variable.  At that time at least one thread waiting
+//               on the same ConditionVarFullDebug will grab the lock again,
+//               and then return from wait().
+//
+//               It is possible that wait() will return even if no one
+//               has called signal().  It is the responsibility of the
+//               calling process to verify the condition on return
+//               from wait, and possibly loop back to wait again if
+//               necessary.
+//
+//               Note the semantics of a condition variable: the mutex
+//               must be held before wait() is called, and it will
+//               still be held when wait() returns.  However, it will
+//               be temporarily released during the wait() call
+//               itself.
+////////////////////////////////////////////////////////////////////
+void ConditionVarFullDebug::
+wait() {
+  _mutex._global_lock->lock();
+
+  if (!_mutex.do_debug_is_locked()) {
+    ostringstream ostr;
+    ostr << *Thread::get_current_thread() << " attempted to wait on "
+         << *this << " without holding " << _mutex;
+    nassert_raise(ostr.str());
+    _mutex._global_lock->release();
+    return;
+  }
+
+  if (thread_cat.is_spam()) {
+    thread_cat.spam()
+      << *Thread::get_current_thread() << " waiting on " << *this << "\n";
+  }
+  
+  _mutex.do_release();
+  _impl.wait();
+  _mutex.do_lock();
+
+  if (thread_cat.is_spam()) {
+    thread_cat.spam()
+      << *Thread::get_current_thread() << " awake on " << *this << "\n";
+  }
+
+  _mutex._global_lock->release();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullDebug::signal
+//       Access: Public
+//  Description: Informs one of the other threads who are currently
+//               blocked on wait() that the relevant condition has
+//               changed.  If multiple threads are currently waiting,
+//               at least one of them will be woken up, although there
+//               is no way to predict which one.  It is possible that
+//               more than one thread will be woken up.
+//
+//               The caller must be holding the mutex associated with
+//               the condition variable before making this call, which
+//               will not release the mutex.
+//
+//               If no threads are waiting, this is a no-op: the
+//               signal is lost.
+////////////////////////////////////////////////////////////////////
+void ConditionVarFullDebug::
+signal() {
+  _mutex._global_lock->lock();
+  if (!_mutex.do_debug_is_locked()) {
+    ostringstream ostr;
+    ostr << *Thread::get_current_thread() << " attempted to signal "
+         << *this << " without holding " << _mutex;
+    nassert_raise(ostr.str());
+    _mutex._global_lock->release();
+    return;
+  }
+
+  if (thread_cat.is_spam()) {
+    thread_cat.spam()
+      << *Thread::get_current_thread() << " signalling " << *this << "\n";
+  }
+
+  _impl.signal();
+  _mutex._global_lock->release();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullDebug::signal
+//       Access: Public
+//  Description: Informs all of the other threads who are currently
+//               blocked on wait() that the relevant condition has
+//               changed.
+//
+//               The caller must be holding the mutex associated with
+//               the condition variable before making this call, which
+//               will not release the mutex.
+//
+//               If no threads are waiting, this is a no-op: the
+//               signal is lost.
+////////////////////////////////////////////////////////////////////
+void ConditionVarFullDebug::
+signal_all() {
+  _mutex._global_lock->lock();
+  if (!_mutex.do_debug_is_locked()) {
+    ostringstream ostr;
+    ostr << *Thread::get_current_thread() << " attempted to signal "
+         << *this << " without holding " << _mutex;
+    nassert_raise(ostr.str());
+    _mutex._global_lock->release();
+    return;
+  }
+
+  if (thread_cat.is_spam()) {
+    thread_cat.spam()
+      << *Thread::get_current_thread() << " signalling all " << *this << "\n";
+  }
+
+  _impl.signal_all();
+  _mutex._global_lock->release();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullDebug::output
+//       Access: Public, Virtual
+//  Description: This method is declared virtual in ConditionVarFullDebug,
+//               but non-virtual in ConditionVarFullDirect.
+////////////////////////////////////////////////////////////////////
+void ConditionVarFullDebug::
+output(ostream &out) const {
+  out << "ConditionVarFull " << (void *)this << " on " << _mutex;
+}
+
+#endif  // DEBUG_THREADS

+ 71 - 0
panda/src/pipeline/conditionVarFullDebug.h

@@ -0,0 +1,71 @@
+// Filename: conditionVarFullDebug.h
+// Created by:  drose (28Aug06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef CONDITIONVARFULLDEBUG_H
+#define CONDITIONVARFULLDEBUG_H
+
+#include "pandabase.h"
+#include "pmutex.h"
+#include "conditionVarImpl.h"
+
+#ifdef DEBUG_THREADS
+
+////////////////////////////////////////////////////////////////////
+//       Class : ConditionVarFullDebug
+// Description : A condition variable, usually used to communicate
+//               information about changing state to a thread that is
+//               waiting for something to happen.  A condition
+//               variable can be used to "wake up" a thread when some
+//               arbitrary condition has changed.
+//
+//               A condition variable is associated with a single
+//               mutex, and several condition variables may share the
+//               same mutex.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA ConditionVarFullDebug {
+public:
+  ConditionVarFullDebug(MutexDebug &mutex);
+  virtual ~ConditionVarFullDebug();
+private:
+  INLINE ConditionVarFullDebug(const ConditionVarFullDebug &copy);
+  INLINE void operator = (const ConditionVarFullDebug &copy);
+
+public:
+  INLINE MutexDebug &get_mutex() const;
+
+  void wait();
+  void signal();
+  void signal_all();
+  virtual void output(ostream &out) const;
+
+private:
+  MutexDebug &_mutex;
+  ConditionVarFullImpl _impl;
+};
+
+INLINE ostream &
+operator << (ostream &out, const ConditionVarFullDebug &cv) {
+  cv.output(out);
+  return out;
+}
+
+#include "conditionVarFullDebug.I"
+
+#endif  // DEBUG_THREADS
+
+#endif

+ 152 - 0
panda/src/pipeline/conditionVarFullDirect.I

@@ -0,0 +1,152 @@
+// Filename: conditionVarFullDirect.I
+// Created by:  drose (28Aug06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullDirect::Constructor
+//       Access: Public
+//  Description: You must pass in a Mutex to the condition variable
+//               constructor.  This mutex may be shared by other
+//               condition variables, if desired.  It is the caller's
+//               responsibility to ensure the Mutex object does not
+//               destruct during the lifetime of the condition
+//               variable.
+////////////////////////////////////////////////////////////////////
+INLINE ConditionVarFullDirect::
+ConditionVarFullDirect(MutexDirect &mutex) :
+  _mutex(mutex),
+  _impl(mutex._impl)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullDirect::Destructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE ConditionVarFullDirect::
+~ConditionVarFullDirect() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullDirect::Copy Constructor
+//       Access: Private
+//  Description: Do not attempt to copy condition variables.
+////////////////////////////////////////////////////////////////////
+INLINE ConditionVarFullDirect::
+ConditionVarFullDirect(const ConditionVarFullDirect &copy) : 
+  _mutex(copy._mutex), 
+  _impl(_mutex._impl)
+{
+  nassertv(false);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullDirect::Copy Assignment Operator
+//       Access: Private
+//  Description: Do not attempt to copy condition variables.
+////////////////////////////////////////////////////////////////////
+INLINE void ConditionVarFullDirect::
+operator = (const ConditionVarFullDirect &copy) {
+  nassertv(false);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullDirect::get_mutex
+//       Access: Public
+//  Description: Returns the mutex associated with this condition
+//               variable.
+////////////////////////////////////////////////////////////////////
+INLINE MutexDirect &ConditionVarFullDirect::
+get_mutex() const {
+  return _mutex;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullDirect::wait
+//       Access: Public
+//  Description: Waits on the condition.  The caller must already be
+//               holding the lock associated with the condition
+//               variable before calling this function.
+//
+//               wait() will release the lock, then go to sleep until
+//               some other thread calls signal() on this condition
+//               variable.  At that time at least one thread waiting
+//               on the same ConditionVarFullDirect will grab the lock again,
+//               and then return from wait().
+//
+//               It is possible that wait() will return even if no one
+//               has called signal().  It is the responsibility of the
+//               calling process to verify the condition on return
+//               from wait, and possibly loop back to wait again if
+//               necessary.
+//
+//               Note the semantics of a condition variable: the mutex
+//               must be held before wait() is called, and it will
+//               still be held when wait() returns.  However, it will
+//               be temporarily released during the wait() call
+//               itself.
+////////////////////////////////////////////////////////////////////
+INLINE void ConditionVarFullDirect::
+wait() {
+  TAU_PROFILE("ConditionVarFullDirect::wait()", " ", TAU_USER);
+  _impl.wait();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullDirect::signal
+//       Access: Public
+//  Description: Informs one of the other threads who are currently
+//               blocked on wait() that the relevant condition has
+//               changed.  If multiple threads are currently waiting,
+//               at least one of them will be woken up, although there
+//               is no way to predict which one.  It is possible that
+//               more than one thread will be woken up.
+//
+//               The caller must be holding the mutex associated with
+//               the condition variable before making this call, which
+//               will not release the mutex.
+//
+//               If no threads are waiting, this is a no-op: the
+//               signal is lost.
+////////////////////////////////////////////////////////////////////
+INLINE void ConditionVarFullDirect::
+signal() {
+  TAU_PROFILE("ConditionVarFullDirect::signal()", " ", TAU_USER);
+  _impl.signal();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullDirect::signal_all
+//       Access: Public
+//  Description: Informs all of the other threads who are currently
+//               blocked on wait() that the relevant condition has
+//               changed.
+//
+//               The caller must be holding the mutex associated with
+//               the condition variable before making this call, which
+//               will not release the mutex.
+//
+//               If no threads are waiting, this is a no-op: the
+//               signal is lost.
+////////////////////////////////////////////////////////////////////
+INLINE void ConditionVarFullDirect::
+signal_all() {
+  TAU_PROFILE("ConditionVarFullDirect::signal()", " ", TAU_USER);
+  _impl.signal_all();
+}

+ 12 - 17
panda/src/pipeline/conditionVarLinuxImpl.I → panda/src/pipeline/conditionVarFullDirect.cxx

@@ -1,5 +1,5 @@
-// Filename: conditionVarLinuxImpl.I
-// Created by:  drose (28Mar06)
+// Filename: conditionVarFullDirect.cxx
+// Created by:  drose (28Aug06)
 //
 ////////////////////////////////////////////////////////////////////
 //
@@ -16,24 +16,19 @@
 //
 ////////////////////////////////////////////////////////////////////
 
+#include "conditionVarFullDirect.h"
 
-////////////////////////////////////////////////////////////////////
-//     Function: ConditionVarLinuxImpl::Constructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE ConditionVarLinuxImpl::
-ConditionVarLinuxImpl(MutexLinuxImpl &mutex) :
-  _mutex(mutex)
-{
-  _counter = 0;
-}
+#ifndef DEBUG_THREADS
 
 ////////////////////////////////////////////////////////////////////
-//     Function: ConditionVarLinuxImpl::Destructor
+//     Function: ConditionVarFullDirect::output
 //       Access: Public
-//  Description:
+//  Description: This method is declared virtual in ConditionVarFullDebug,
+//               but non-virtual in ConditionVarFullDirect.
 ////////////////////////////////////////////////////////////////////
-INLINE ConditionVarLinuxImpl::
-~ConditionVarLinuxImpl() {
+void ConditionVarFullDirect::
+output(ostream &out) const {
+  out << "ConditionVarFull " << (void *)this << " on " << _mutex;
 }
+
+#endif  // !DEBUG_THREADS

+ 71 - 0
panda/src/pipeline/conditionVarFullDirect.h

@@ -0,0 +1,71 @@
+// Filename: conditionVarFullDirect.h
+// Created by:  drose (28Aug06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef CONDITIONVARFULLDIRECT_H
+#define CONDITIONVARFULLDIRECT_H
+
+#include "pandabase.h"
+#include "mutexDirect.h"
+#include "conditionVarImpl.h"
+
+#ifndef DEBUG_THREADS
+
+////////////////////////////////////////////////////////////////////
+//       Class : ConditionVarFullDirect
+// Description : A condition variable, usually used to communicate
+//               information about changing state to a thread that is
+//               waiting for something to happen.  A condition
+//               variable can be used to "wake up" a thread when some
+//               arbitrary condition has changed.
+//
+//               A condition variable is associated with a single
+//               mutex, and several condition variables may share the
+//               same mutex.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA ConditionVarFullDirect {
+public:
+  INLINE ConditionVarFullDirect(MutexDirect &mutex);
+  INLINE ~ConditionVarFullDirect();
+private:
+  INLINE ConditionVarFullDirect(const ConditionVarFullDirect &copy);
+  INLINE void operator = (const ConditionVarFullDirect &copy);
+
+public:
+  INLINE MutexDirect &get_mutex() const;
+
+  INLINE void wait();
+  INLINE void signal();
+  INLINE void signal_all();
+  void output(ostream &out) const;
+
+private:
+  MutexDirect &_mutex;
+  ConditionVarFullImpl _impl;
+};
+
+INLINE ostream &
+operator << (ostream &out, const ConditionVarFullDirect &cv) {
+  cv.output(out);
+  return out;
+}
+
+#include "conditionVarFullDirect.I"
+
+#endif  // !DEBUG_THREADS
+
+#endif

+ 77 - 0
panda/src/pipeline/conditionVarFullWin32Impl.I

@@ -0,0 +1,77 @@
+// Filename: conditionVarFullWin32Impl.I
+// Created by:  drose (28Aug06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullWin32Impl::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE ConditionVarFullWin32Impl::
+ConditionVarFullWin32Impl(MutexWin32Impl &mutex) {
+  _external_mutex = &mutex._lock;
+
+  // Create an auto-reset event.
+  _event_signal = CreateEvent(NULL, false, false, NULL);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullWin32Impl::Destructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE ConditionVarFullWin32Impl::
+~ConditionVarFullWin32Impl() {
+  CloseHandle(_event_signal);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullWin32Impl::wait
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE void ConditionVarFullWin32Impl::
+wait() {
+  LeaveCriticalSection(_external_mutex);
+
+  DWORD result = WaitForSingleObject(_event_signal, INFINITE);
+  nassertv(result == WAIT_OBJECT_0);
+
+  EnterCriticalSection(_external_mutex);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullWin32Impl::signal
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE void ConditionVarFullWin32Impl::
+signal() {
+  SetEvent(_event_signal);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarFullWin32Impl::signal_all
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE void ConditionVarFullWin32Impl::
+signal_all() {
+  // TODO.
+  nassertv(false);
+}

+ 25 - 0
panda/src/pipeline/conditionVarFullWin32Impl.cxx

@@ -0,0 +1,25 @@
+// Filename: conditionVarFullWin32Impl.cxx
+// Created by:  drose (28Aug06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "selectThreadImpl.h"
+
+#ifdef WIN32_VC
+
+#include "conditionVarFullWin32Impl.h"
+
+#endif  // WIN32_VC

+ 65 - 0
panda/src/pipeline/conditionVarFullWin32Impl.h

@@ -0,0 +1,65 @@
+// Filename: conditionVarFullWin32Impl.h
+// Created by:  drose (28Aug06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef CONDITIONVARFULLWIN32IMPL_H
+#define CONDITIONVARFULLWIN32IMPL_H
+
+#include "pandabase.h"
+#include "selectThreadImpl.h"
+
+#ifdef WIN32_VC
+
+#include "mutexWin32Impl.h"
+#include "pnotify.h"
+
+class MutexWin32Impl;
+
+////////////////////////////////////////////////////////////////////
+//       Class : ConditionVarFullWin32Impl
+// Description : Uses Windows native calls to implement a
+//               conditionVarFull.
+//
+//               The Windows native synchronization primitives don't
+//               actually implement a full POSIX-style condition
+//               variable, but the Event primitive does a fair job if
+//               we disallow POSIX broadcast.  See
+//               http://www.cs.wustl.edu/~schmidt/win32-cv-1.html for
+//               a full implementation that includes broadcast.  This
+//               class is much simpler than that full implementation,
+//               so we can avoid the overhead require to support
+//               broadcast.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA ConditionVarFullWin32Impl {
+public:
+  INLINE ConditionVarFullWin32Impl(MutexWin32Impl &mutex);
+  INLINE ~ConditionVarFullWin32Impl();
+
+  INLINE void wait();
+  INLINE void signal();
+  INLINE void signal_all();
+
+private:
+  CRITICAL_SECTION *_external_mutex;
+  HANDLE _event_signal;
+};
+
+#include "conditionVarFullWin32Impl.I"
+
+#endif  // WIN32_VC
+
+#endif

+ 6 - 5
panda/src/pipeline/conditionVarImpl.h

@@ -26,31 +26,32 @@
 
 #include "conditionVarDummyImpl.h"
 typedef ConditionVarDummyImpl ConditionVarImpl;
+typedef ConditionVarDummyImpl ConditionVarFullImpl;
 
 #elif defined(MUTEX_SPINLOCK)
 
 #include "conditionVarSpinlockImpl.h"
 typedef ConditionVarSpinlockImpl ConditionVarImpl;
+typedef ConditionVarSpinlockImpl ConditionVarFullImpl;
 
 #elif defined(THREAD_WIN32_IMPL)
 
 #include "conditionVarWin32Impl.h"
+#include "conditionVarFullWin32Impl.h"
 typedef ConditionVarWin32Impl ConditionVarImpl;
-
-#elif defined(THREAD_LINUX_IMPL)
-
-#include "conditionVarLinuxImpl.h"
-typedef ConditionVarLinuxImpl ConditionVarImpl;
+typedef ConditionVarFullWin32Impl ConditionVarFullImpl;
 
 #elif defined(THREAD_POSIX_IMPL)
 
 #include "conditionVarPosixImpl.h"
 typedef ConditionVarPosixImpl ConditionVarImpl;
+typedef ConditionVarPosixImpl ConditionVarFullImpl;
 
 #elif defined(THREAD_NSPR_IMPL)
 
 #include "conditionVarNsprImpl.h"
 typedef ConditionVarNsprImpl ConditionVarImpl;
+typedef ConditionVarNsprImpl ConditionVarFullImpl;
 
 #endif
 

+ 0 - 55
panda/src/pipeline/conditionVarLinuxImpl.cxx

@@ -1,55 +0,0 @@
-// Filename: conditionVarLinuxImpl.cxx
-// Created by:  drose (28Mar06)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#include "selectThreadImpl.h"
-
-#ifdef HAVE_LINUX_NATIVE_THREADS
-
-#include "conditionVarLinuxImpl.h"
-
-#include <linux/futex.h>
-#include <sys/time.h>
-#include <sys/syscall.h>
-
-////////////////////////////////////////////////////////////////////
-//     Function: ConditionVarLinuxImpl::wait
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-void ConditionVarLinuxImpl::
-wait() {
-  // Grab the current value of the counter before we release the
-  // mutex.
-  PN_int32 orig_counter = _counter;
-  _mutex.release();
-  syscall(SYS_futex, &_counter, FUTEX_WAIT, orig_counter, (void *)NULL);
-  _mutex.lock();
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ConditionVarLinuxImpl::signal
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-void ConditionVarLinuxImpl::
-signal() {
-  AtomicAdjust::inc(_counter);
-  syscall(SYS_futex, &_counter, FUTEX_WAKE, 1);
-}
-
-#endif  // HAVE_LINUX_NATIVE_THREADS

+ 0 - 53
panda/src/pipeline/conditionVarLinuxImpl.h

@@ -1,53 +0,0 @@
-// Filename: conditionVarLinuxImpl.h
-// Created by:  drose (28Mar06)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#ifndef CONDITIONVARLINUXIMPL_H
-#define CONDITIONVARLINUXIMPL_H
-
-#include "pandabase.h"
-#include "selectThreadImpl.h"
-
-#ifdef HAVE_LINUX_NATIVE_THREADS
-
-#include "mutexLinuxImpl.h"
-#include "pnotify.h"
-
-class MutexLinuxImpl;
-
-////////////////////////////////////////////////////////////////////
-//       Class : ConditionVarLinuxImpl
-// Description : Uses Linux threads to implement a conditionVar.
-////////////////////////////////////////////////////////////////////
-class EXPCL_PANDA ConditionVarLinuxImpl {
-public:
-  INLINE ConditionVarLinuxImpl(MutexLinuxImpl &mutex);
-  INLINE ~ConditionVarLinuxImpl();
-
-  void wait();
-  void signal();
-
-private:
-  MutexLinuxImpl &_mutex;
-  PN_int32 _counter;
-};
-
-#include "conditionVarLinuxImpl.I"
-
-#endif  // HAVE_LINUX_NATIVE_THREADS
-
-#endif

+ 11 - 0
panda/src/pipeline/conditionVarNsprImpl.I

@@ -59,3 +59,14 @@ signal() {
   int status = PR_NotifyCondVar(_cvar);
   nassertv(status == PR_SUCCESS);
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarNsprImpl::signal_all
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE void ConditionVarNsprImpl::
+signal_all() {
+  int status = PR_NotifyAllCondVar(_cvar);
+  nassertv(status == PR_SUCCESS);
+}

+ 1 - 0
panda/src/pipeline/conditionVarNsprImpl.h

@@ -42,6 +42,7 @@ public:
 
   INLINE void wait();
   INLINE void signal();
+  INLINE void signal_all();
 
 private:
   PRCondVar *_cvar;

+ 12 - 0
panda/src/pipeline/conditionVarPosixImpl.I

@@ -66,3 +66,15 @@ signal() {
   int result = pthread_cond_signal(&_cvar);
   nassertv(result == 0);
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarPosixImpl::signal_all
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE void ConditionVarPosixImpl::
+signal_all() {
+  TAU_PROFILE("ConditionVarPosixImpl::signal()", " ", TAU_USER);
+  int result = pthread_cond_broadcast(&_cvar);
+  nassertv(result == 0);
+}

+ 1 - 0
panda/src/pipeline/conditionVarPosixImpl.h

@@ -42,6 +42,7 @@ public:
 
   INLINE void wait();
   INLINE void signal();
+  INLINE void signal_all();
 
 private:
   MutexPosixImpl &_mutex;

+ 10 - 0
panda/src/pipeline/conditionVarSpinlockImpl.I

@@ -46,3 +46,13 @@ signal() {
   // This will wake up all waiters on the lock.  But that's allowed.
   AtomicAdjust::inc(_event);
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConditionVarSpinlockImpl::signal_all
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE void ConditionVarSpinlockImpl::
+signal_all() {
+  AtomicAdjust::inc(_event);
+}

+ 1 - 0
panda/src/pipeline/conditionVarSpinlockImpl.h

@@ -46,6 +46,7 @@ public:
 
   void wait();
   INLINE void signal();
+  INLINE void signal_all();
 
 private:
   MutexSpinlockImpl &_mutex;

+ 1 - 0
panda/src/pipeline/mutexDebug.h

@@ -71,6 +71,7 @@ private:
   static MutexImpl *_global_lock;
 
   friend class ConditionVarDebug;
+  friend class ConditionVarFullDebug;
 };
 
 INLINE ostream &

+ 1 - 0
panda/src/pipeline/mutexDirect.h

@@ -52,6 +52,7 @@ private:
   MutexImpl _impl;
 
   friend class ConditionVarDirect;
+  friend class ConditionVarFullDirect;
 };
 
 INLINE ostream &

+ 3 - 1
panda/src/pipeline/pipeline_composite1.cxx

@@ -2,8 +2,10 @@
 #include "conditionVarDebug.cxx"
 #include "conditionVarDirect.cxx"
 #include "conditionVarDummyImpl.cxx"
+#include "conditionVarFull.cxx"
+#include "conditionVarFullDebug.cxx"
+#include "conditionVarFullDirect.cxx"
 #include "conditionVarNsprImpl.cxx"
-#include "conditionVarLinuxImpl.cxx"
 #include "conditionVarPosixImpl.cxx"
 #include "conditionVarWin32Impl.cxx"
 #include "conditionVarSpinlockImpl.cxx"

+ 0 - 1
panda/src/pipeline/pipeline_composite2.cxx

@@ -15,6 +15,5 @@
 #include "thread.cxx"
 #include "threadDummyImpl.cxx"
 #include "threadNsprImpl.cxx"
-#include "threadLinuxImpl.cxx"
 #include "threadPosixImpl.cxx"
 #include "threadWin32Impl.cxx"

+ 0 - 1
panda/src/pipeline/thread.h

@@ -130,7 +130,6 @@ private:
 
   friend class ThreadDummyImpl;
   friend class ThreadWin32Impl;
-  friend class ThreadLinuxImpl;
   friend class ThreadPosixImpl;
   friend class ThreadNsprImpl;
 };

+ 0 - 5
panda/src/pipeline/threadImpl.h

@@ -32,11 +32,6 @@ typedef ThreadDummyImpl ThreadImpl;
 #include "threadWin32Impl.h"
 typedef ThreadWin32Impl ThreadImpl;
 
-#elif defined(THREAD_LINUX_IMPL)
-
-#include "threadLinuxImpl.h"
-typedef ThreadLinuxImpl ThreadImpl;
-
 #elif defined(THREAD_POSIX_IMPL)
 
 #include "threadPosixImpl.h"

+ 0 - 260
panda/src/pipeline/threadLinuxImpl.cxx

@@ -1,260 +0,0 @@
-// Filename: threadLinuxImpl.cxx
-// Created by:  drose (28Mar06)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#include "threadLinuxImpl.h"
-#include "selectThreadImpl.h"
-
-#ifdef THREAD_LINUX_IMPL
-
-#include "pointerTo.h"
-#include "config_pipeline.h"
-
-#include <sched.h>
-#include <sys/types.h>
-#include <linux/unistd.h>
-#include <signal.h>
-#include <stdio.h>   // for perror
-
-MutexLinuxImpl ThreadLinuxImpl::_thread_pointers_lock;
-ThreadLinuxImpl::ThreadPointers ThreadLinuxImpl::_thread_pointers;
-bool ThreadLinuxImpl::_got_main_thread_pointer;
-
-inline static pid_t gettid() {
-#ifdef __i386__
-  pid_t ret;
-  __asm__("int $0x80" : "=a" (ret) : "0" (224) /* SYS_gettid */);
-  return ret;
-#else
-#error only i386 supported right now.
-#endif
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ThreadLinuxImpl::Destructor
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-ThreadLinuxImpl::
-~ThreadLinuxImpl() {
-  if (thread_cat.is_debug()) {
-    thread_cat.debug() << "Deleting thread " << _parent_obj->get_name() << "\n";
-  }
-
-  if (_stack != NULL) {
-    delete[] _stack;
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ThreadLinuxImpl::start
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-bool ThreadLinuxImpl::
-start(ThreadPriority priority, bool global, bool joinable) {
-  _mutex.lock();
-  if (thread_cat.is_debug()) {
-    thread_cat.debug() << "Starting " << *_parent_obj << "\n";
-  }
-
-  nassertd(_status == S_new && _thread == 0 && _stack == NULL) {
-    _mutex.release();
-    return false;
-  }
-
-  _joinable = joinable;
-  _status = S_start_called;
-
-  if (!_got_main_thread_pointer) {
-    // If we haven't spawned any threads yet, this must be the main
-    // thread.
-    bind_thread(Thread::get_main_thread());
-    _got_main_thread_pointer = true;
-  }
-
-  // Increment the parent object's reference count first.  The thread
-  // will eventually decrement it when it terminates.
-  _parent_obj->ref();
-
-  _stack = new unsigned char[thread_stack_size];
-
-  int flags = SIGCHLD | CLONE_PARENT | CLONE_VM;
-  if (!global) {
-    // Make a thread that uses the same pid as the parent.
-    flags |= CLONE_SIGHAND | CLONE_THREAD;
-  }
-
-  _thread = 
-    clone(&root_func, _stack + thread_stack_size, 
-          flags, (void *)this);
-
-  if (_thread == -1) {
-    // Oops, we couldn't start the thread.  Be sure to decrement the
-    // reference count we incremented above, and return false to
-    // indicate failure.
-    perror("clone");
-    unref_delete(_parent_obj);
-    _mutex.release();
-    return false;
-  }
-
-  _mutex.release();
-  return true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ThreadLinuxImpl::interrupt
-//       Access: Public
-//  Description: Sends an interrupt message to the thread.  This will
-//               interrupt any blocking-type system calls the thread
-//               may be waiting on, such as I/O, so that the thread
-//               may continue some other processing.  The specific
-//               behavior is implementation dependent.
-////////////////////////////////////////////////////////////////////
-void ThreadLinuxImpl::
-interrupt() {
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ThreadLinuxImpl::join
-//       Access: Public
-//  Description: Blocks the calling process until the thread
-//               terminates.  If the thread has already terminated,
-//               this returns immediately.
-////////////////////////////////////////////////////////////////////
-void ThreadLinuxImpl::
-join() {
-  _mutex.lock();
-  nassertd(_joinable && _status != S_new) {
-    _mutex.release();
-    return;
-  }
-
-  while (_status != S_finished) {
-    _cv.wait();
-  }
-  _mutex.release();
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ThreadLinuxImpl::get_current_thread
-//       Access: Public, Static
-//  Description: 
-////////////////////////////////////////////////////////////////////
-Thread *ThreadLinuxImpl::
-get_current_thread() {
-  if (!_got_main_thread_pointer) {
-    // If we haven't spawned any threads yet, this must be the main
-    // thread.
-    bind_thread(Thread::get_main_thread());
-    _got_main_thread_pointer = true;
-    return Thread::get_main_thread();
-  }
-
-  _thread_pointers_lock.lock();
-  Thread *result = NULL;
-
-  ThreadPointers::const_iterator ti;
-  pid_t my_tid = gettid();
-  ti = _thread_pointers.find(my_tid);
-  if (ti != _thread_pointers.end()) {
-    result = (*ti).second;
-  }
-  _thread_pointers_lock.release();
-
-  nassertr(result != NULL, NULL);
-  return result;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ThreadLinuxImpl::bind_thread
-//       Access: Public, Static
-//  Description: Associates the indicated Thread object with the
-//               currently-executing thread.  You should not call this
-//               directly; use Thread::bind_thread() instead.
-////////////////////////////////////////////////////////////////////
-void ThreadLinuxImpl::
-bind_thread(Thread *thread) {
-  _thread_pointers_lock.lock();
-  pid_t my_tid = gettid();
-  bool inserted = _thread_pointers.insert(ThreadPointers::value_type(my_tid, thread)).second;
-  _thread_pointers_lock.release();
-  nassertv(inserted);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ThreadLinuxImpl::root_func
-//       Access: Private, Static
-//  Description: The entry point of each thread.
-////////////////////////////////////////////////////////////////////
-int ThreadLinuxImpl::
-root_func(void *data) {
-  ThreadLinuxImpl *self = (ThreadLinuxImpl *)data;
-
-  {
-    _thread_pointers_lock.lock();
-    pid_t my_tid = gettid();
-
-    bool inserted = _thread_pointers.insert(ThreadPointers::value_type(my_tid, self->_parent_obj)).second;
-    nassertd(inserted) {
-      _thread_pointers_lock.release();
-      return 1;
-    }
-    _thread_pointers_lock.release();
-  }
-
-  {
-    self->_mutex.lock();
-    nassertd(self->_status == S_start_called) {
-      self->_mutex.release();
-      return 1;
-    }
-    
-    self->_status = S_running;
-    self->_cv.signal();
-    self->_mutex.release();
-  }
-
-  self->_parent_obj->thread_main();
-
-  if (thread_cat.is_debug()) {
-    thread_cat.debug()
-      << "Terminating thread " << self->_parent_obj->get_name() 
-      << ", count = " << self->_parent_obj->get_ref_count() << "\n";
-  }
-
-  {
-    self->_mutex.lock();
-    nassertd(self->_status == S_running) {
-      self->_mutex.release();
-      return 1;
-    }
-    self->_status = S_finished;
-    self->_cv.signal();
-    self->_mutex.release();
-  }
-
-  // Now drop the parent object reference that we grabbed in start().
-  // This might delete the parent object, and in turn, delete the
-  // ThreadLinuxImpl object.
-  unref_delete(self->_parent_obj);
-
-  return 0;
-}
-
-#endif  // THREAD_LINUX_IMPL

+ 0 - 84
panda/src/pipeline/threadLinuxImpl.h

@@ -1,84 +0,0 @@
-// Filename: threadLinuxImpl.h
-// Created by:  drose (28Mar06)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#ifndef THREADLINUXIMPL_H
-#define THREADLINUXIMPL_H
-
-#include "pandabase.h"
-#include "selectThreadImpl.h"
-
-#ifdef THREAD_LINUX_IMPL
-
-#include "pnotify.h"
-#include "threadPriority.h"
-#include "mutexLinuxImpl.h"
-#include "conditionVarLinuxImpl.h"
-
-class Thread;
-
-////////////////////////////////////////////////////////////////////
-//       Class : ThreadLinuxImpl
-// Description : Uses low-level Linux-specific calls to implement
-//               threads.
-////////////////////////////////////////////////////////////////////
-class EXPCL_PANDA ThreadLinuxImpl {
-public:
-  INLINE ThreadLinuxImpl(Thread *parent_obj);
-  ~ThreadLinuxImpl();
-
-  bool start(ThreadPriority priority, bool global, bool joinable);
-  void interrupt();
-  void join();
-
-  INLINE static void prepare_for_exit();
-
-  static Thread *get_current_thread();
-  static void bind_thread(Thread *thread);
-  INLINE static bool is_threading_supported();
-  INLINE static void sleep(double seconds);
-
-private:
-  static int root_func(void *data);
-
-  enum Status {
-    S_new,
-    S_start_called,
-    S_running,
-    S_finished
-  };
-
-  MutexLinuxImpl _mutex;
-  ConditionVarLinuxImpl _cv;
-  Thread *_parent_obj;
-  int _thread;
-  bool _joinable;
-  Status _status;
-  unsigned char *_stack;
-
-  // per-thread data.
-  typedef pmap<pid_t, Thread *> ThreadPointers;
-  static ThreadPointers _thread_pointers;
-  static MutexLinuxImpl _thread_pointers_lock;
-  static bool _got_main_thread_pointer;
-};
-
-#include "threadLinuxImpl.I"
-
-#endif  // THREAD_LINUX_IMPL
-
-#endif