fix deadlock issues

This commit is contained in:
David Rose 2006-07-14 16:16:33 +00:00
parent 6b04e6e4f4
commit ab3fe7e180
2 changed files with 29 additions and 31 deletions

View File

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

View File

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