diff --git a/panda/src/pipeline/threadSimpleManager.cxx b/panda/src/pipeline/threadSimpleManager.cxx index 4406fc1218..147ec53ef9 100644 --- a/panda/src/pipeline/threadSimpleManager.cxx +++ b/panda/src/pipeline/threadSimpleManager.cxx @@ -302,9 +302,19 @@ next_context() { void ThreadSimpleManager:: prepare_for_exit() { if (!_current_thread->_parent_obj->is_exact_type(MainThread::get_class_type())) { + if (thread_cat->is_debug()) { + thread_cat.debug() + << "Ignoring prepare_for_exit called from " + << *(_current_thread->_parent_obj) << "\n"; + } return; } + if (thread_cat->is_debug()) { + thread_cat.debug() + << "prepare_for_exit\n"; + } + nassertv(_waiting_for_exit == NULL); _waiting_for_exit = _current_thread; @@ -586,6 +596,18 @@ choose_next_context() { } else { // No threads are ready! + if (_waiting_for_exit != NULL) { + // This is a shutdown situation. In this case, we quietly + // abandoned the remaining blocked threads, if any, and + // switch back to the main thread to finish shutting down. + _ready.push_back(_waiting_for_exit); + _waiting_for_exit = NULL; + break; + } + + // No threads are ready to rull, but we're not explicitly + // shutting down. This is an error condition, an + // unintentional deadlock. if (!_blocked.empty()) { thread_cat->error() << "Deadlock! All threads blocked.\n"; @@ -593,15 +615,6 @@ choose_next_context() { abort(); } - // All threads have finished execution. - if (_waiting_for_exit != NULL) { - // And one thread--presumably the main thread--was waiting for - // that. - _ready.push_back(_waiting_for_exit); - _waiting_for_exit = NULL; - break; - } - // No threads are queued anywhere. This is some kind of // internal error, since normally the main thread, at least, // should be queued somewhere.