Browse Source

fix deadlock issues

David Rose 19 years ago
parent
commit
ab3fe7e180
2 changed files with 29 additions and 31 deletions
  1. 26 29
      panda/src/display/graphicsEngine.cxx
  2. 3 2
      panda/src/display/graphicsEngine.h

+ 26 - 29
panda/src/display/graphicsEngine.cxx

@@ -31,6 +31,7 @@
 #include "pStatClient.h"
 #include "pStatCollector.h"
 #include "mutexHolder.h"
+#include "reMutexHolder.h"
 #include "cullFaceAttrib.h"
 #include "string_utils.h"
 #include "geomCacheManager.h"
@@ -164,7 +165,7 @@ set_threading_model(const GraphicsThreadingModel &threading_model) {
       << "Danger!  Creating requested render threads anyway!\n";
   }
 #endif  // THREADED_PIPELINE
-  MutexHolder holder(_lock);
+  ReMutexHolder holder(_lock);
   _threading_model = threading_model;
 }
 
@@ -178,7 +179,7 @@ GraphicsThreadingModel GraphicsEngine::
 get_threading_model() const {
   GraphicsThreadingModel result;
   {
-    MutexHolder holder(_lock);
+    ReMutexHolder holder(_lock);
     result = _threading_model;
   }
   return result;
@@ -420,7 +421,7 @@ remove_window(GraphicsOutput *window) {
   PT(GraphicsOutput) ptwin = window;
   size_t count;
   {
-    MutexHolder holder(_lock);
+    ReMutexHolder holder(_lock, current_thread);
     if (!_windows_sorted) {
       do_resort_windows();
     }
@@ -557,11 +558,7 @@ render_frame() {
       << "render_frame() - frame " << global_clock->get_frame_count() << "\n";
   }
 
-  // We hold the GraphicsEngine mutex while we wait for all of the
-  // threads.  Doing this puts us at risk for deadlock if any of the
-  // threads tries to call any methods on the GraphicsEngine.  So
-  // don't do that.
-  MutexHolder holder(_lock);
+  ReMutexHolder holder(_lock, current_thread);
 
   if (!_windows_sorted) {
     do_resort_windows();
@@ -757,7 +754,7 @@ void GraphicsEngine::
 open_windows() {
   Thread *current_thread = Thread::get_current_thread();
 
-  MutexHolder holder(_lock);
+  ReMutexHolder holder(_lock, current_thread);
 
   if (!_windows_sorted) {
     do_resort_windows();
@@ -798,7 +795,7 @@ open_windows() {
 void GraphicsEngine::
 sync_frame() {
   Thread *current_thread = Thread::get_current_thread();
-  MutexHolder holder(_lock);
+  ReMutexHolder holder(_lock, current_thread);
 
   if (_flip_state == FS_draw) {
     do_sync_frame(current_thread);
@@ -817,7 +814,7 @@ sync_frame() {
 void GraphicsEngine::
 flip_frame() {
   Thread *current_thread = Thread::get_current_thread();
-  MutexHolder holder(_lock);
+  ReMutexHolder holder(_lock, current_thread);
 
   if (_flip_state != FS_flip) {
     do_flip_frame(current_thread);
@@ -855,7 +852,7 @@ flip_frame() {
 ////////////////////////////////////////////////////////////////////
 bool GraphicsEngine::
 extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg) {
-  MutexHolder holder(_lock);
+  ReMutexHolder holder(_lock);
 
   string draw_name = gsg->get_threading_model().get_draw_name();
   if (draw_name.empty()) {
@@ -902,7 +899,7 @@ bool GraphicsEngine::
 add_callback(const string &thread_name, 
              GraphicsEngine::CallbackTime callback_time,
              GraphicsEngine::CallbackFunction *func, void *data) {
-  MutexHolder holder(_lock);
+  ReMutexHolder holder(_lock);
   WindowRenderer *wr = get_window_renderer(thread_name, 0);
   return wr->add_callback(callback_time, Callback(func, data));
 }
@@ -923,7 +920,7 @@ bool GraphicsEngine::
 remove_callback(const string &thread_name,
                 GraphicsEngine::CallbackTime callback_time,
                 GraphicsEngine::CallbackFunction *func, void *data) {
-  MutexHolder holder(_lock);
+  ReMutexHolder holder(_lock);
   WindowRenderer *wr = get_window_renderer(thread_name, 0);
   return wr->remove_callback(callback_time, Callback(func, data));
 }
@@ -940,7 +937,7 @@ remove_callback(const string &thread_name,
 ////////////////////////////////////////////////////////////////////
 void GraphicsEngine::
 set_window_sort(GraphicsOutput *window, int sort) {
-  MutexHolder holder(_lock);
+  ReMutexHolder holder(_lock);
   window->_sort = sort;
   _windows_sorted = false;
 }
@@ -1556,7 +1553,7 @@ do_draw(CullResult *cull_result, SceneSetup *scene_setup,
 void GraphicsEngine::
 do_add_window(GraphicsOutput *window,
               const GraphicsThreadingModel &threading_model) {
-  MutexHolder holder(_lock);
+  ReMutexHolder holder(_lock);
 
   // We have a special counter that is unique per window that allows
   // us to assure that recently-added windows end up on the end of the
@@ -1619,7 +1616,7 @@ do_add_window(GraphicsOutput *window,
 void GraphicsEngine::
 do_add_gsg(GraphicsStateGuardian *gsg, GraphicsPipe *pipe,
            const GraphicsThreadingModel &threading_model) {
-  MutexHolder holder(_lock);
+  ReMutexHolder holder(_lock);
 
   gsg->_threading_model = threading_model;
   gsg->_pipe = pipe;
@@ -1701,7 +1698,7 @@ do_resort_windows() {
 ////////////////////////////////////////////////////////////////////
 void GraphicsEngine::
 terminate_threads(Thread *current_thread) {
-  MutexHolder holder(_lock);
+  ReMutexHolder holder(_lock, current_thread);
 
   // We spend almost our entire time in this method just waiting for
   // threads.  Time it appropriately.
@@ -1849,7 +1846,7 @@ WindowRenderer(const string &name) :
 ////////////////////////////////////////////////////////////////////
 void GraphicsEngine::WindowRenderer::
 add_gsg(GraphicsStateGuardian *gsg) {
-  MutexHolder holder(_wl_lock);
+  ReMutexHolder holder(_wl_lock);
   _gsgs.insert(gsg);
 }
 
@@ -1861,7 +1858,7 @@ add_gsg(GraphicsStateGuardian *gsg) {
 ////////////////////////////////////////////////////////////////////
 void GraphicsEngine::WindowRenderer::
 add_window(Windows &wlist, GraphicsOutput *window) {
-  MutexHolder holder(_wl_lock);
+  ReMutexHolder holder(_wl_lock);
   wlist.insert(window);
 }
 
@@ -1875,7 +1872,7 @@ add_window(Windows &wlist, GraphicsOutput *window) {
 ////////////////////////////////////////////////////////////////////
 void GraphicsEngine::WindowRenderer::
 remove_window(GraphicsOutput *window) {
-  MutexHolder holder(_wl_lock);
+  ReMutexHolder holder(_wl_lock);
   PT(GraphicsOutput) ptwin = window;
 
   _cull.erase(ptwin);
@@ -1910,7 +1907,7 @@ remove_window(GraphicsOutput *window) {
 ////////////////////////////////////////////////////////////////////
 void GraphicsEngine::WindowRenderer::
 resort_windows() {
-  MutexHolder holder(_wl_lock);
+  ReMutexHolder holder(_wl_lock);
 
   _cull.sort();
   _cdraw.sort();
@@ -1942,7 +1939,7 @@ resort_windows() {
 void GraphicsEngine::WindowRenderer::
 do_frame(GraphicsEngine *engine, Thread *current_thread) {
   PStatTimer timer(engine->_do_frame_pcollector, current_thread);
-  MutexHolder holder(_wl_lock);
+  ReMutexHolder holder(_wl_lock);
 
   do_callbacks(CB_pre_frame);
 
@@ -1985,7 +1982,7 @@ do_frame(GraphicsEngine *engine, Thread *current_thread) {
 ////////////////////////////////////////////////////////////////////
 void GraphicsEngine::WindowRenderer::
 do_windows(GraphicsEngine *engine, Thread *current_thread) {
-  MutexHolder holder(_wl_lock);
+  ReMutexHolder holder(_wl_lock);
 
   engine->process_events(_window, current_thread);
 
@@ -2001,7 +1998,7 @@ do_windows(GraphicsEngine *engine, Thread *current_thread) {
 ////////////////////////////////////////////////////////////////////
 void GraphicsEngine::WindowRenderer::
 do_flip(GraphicsEngine *engine, Thread *current_thread) {
-  MutexHolder holder(_wl_lock);
+  ReMutexHolder holder(_wl_lock);
   engine->flip_windows(_cdraw, current_thread);
   engine->flip_windows(_draw, current_thread);
 }
@@ -2013,7 +2010,7 @@ do_flip(GraphicsEngine *engine, Thread *current_thread) {
 ////////////////////////////////////////////////////////////////////
 void GraphicsEngine::WindowRenderer::
 do_close(GraphicsEngine *engine, Thread *current_thread) {
-  MutexHolder holder(_wl_lock);
+  ReMutexHolder holder(_wl_lock);
   Windows::iterator wi;
   for (wi = _window.begin(); wi != _window.end(); ++wi) {
     GraphicsOutput *win = (*wi);
@@ -2046,7 +2043,7 @@ do_close(GraphicsEngine *engine, Thread *current_thread) {
 ////////////////////////////////////////////////////////////////////
 void GraphicsEngine::WindowRenderer::
 do_pending(GraphicsEngine *engine, Thread *current_thread) {
-  MutexHolder holder(_wl_lock);
+  ReMutexHolder holder(_wl_lock);
 
   if (!_pending_close.empty()) {
     // Close any windows that were pending closure.
@@ -2089,7 +2086,7 @@ bool GraphicsEngine::WindowRenderer::
 add_callback(GraphicsEngine::CallbackTime callback_time, 
              const GraphicsEngine::Callback &callback) {
   nassertr(callback_time >= 0 && callback_time < CB_len, false);
-  MutexHolder holder(_wl_lock);
+  ReMutexHolder holder(_wl_lock);
   return _callbacks[callback_time].insert(callback).second;
 }
 
@@ -2105,7 +2102,7 @@ bool GraphicsEngine::WindowRenderer::
 remove_callback(GraphicsEngine::CallbackTime callback_time, 
                 const GraphicsEngine::Callback &callback) {
   nassertr(callback_time >= 0 && callback_time < CB_len, false);
-  MutexHolder holder(_wl_lock);
+  ReMutexHolder holder(_wl_lock);
   Callbacks::iterator cbi = _callbacks[callback_time].find(callback);
   if (cbi != _callbacks[callback_time].end()) {
     _callbacks[callback_time].erase(cbi);

+ 3 - 2
panda/src/display/graphicsEngine.h

@@ -28,6 +28,7 @@
 #include "pointerTo.h"
 #include "thread.h"
 #include "pmutex.h"
+#include "reMutex.h"
 #include "conditionVar.h"
 #include "pStatCollector.h"
 #include "pset.h"
@@ -294,7 +295,7 @@ private:
     GSGs _gsgs;       // draw stage
 
     Callbacks _callbacks[CB_len];
-    Mutex _wl_lock;
+    ReMutex _wl_lock;
   };
 
   class RenderThread : public Thread, public WindowRenderer {
@@ -329,7 +330,7 @@ private:
     FS_flip,  // All windows are done drawing and have flipped.
   };
   FlipState _flip_state;
-  Mutex _lock;
+  ReMutex _lock;
 
   static PStatCollector _wait_pcollector;
   static PStatCollector _cycle_pcollector;