Browse Source

accept threads hanging on shutdown

David Rose 16 years ago
parent
commit
a261e805a3
1 changed files with 22 additions and 9 deletions
  1. 22 9
      panda/src/pipeline/threadSimpleManager.cxx

+ 22 - 9
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.