|
@@ -302,9 +302,19 @@ next_context() {
|
|
|
void ThreadSimpleManager::
|
|
void ThreadSimpleManager::
|
|
|
prepare_for_exit() {
|
|
prepare_for_exit() {
|
|
|
if (!_current_thread->_parent_obj->is_exact_type(MainThread::get_class_type())) {
|
|
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;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if (thread_cat->is_debug()) {
|
|
|
|
|
+ thread_cat.debug()
|
|
|
|
|
+ << "prepare_for_exit\n";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
nassertv(_waiting_for_exit == NULL);
|
|
nassertv(_waiting_for_exit == NULL);
|
|
|
_waiting_for_exit = _current_thread;
|
|
_waiting_for_exit = _current_thread;
|
|
|
|
|
|
|
@@ -586,6 +596,18 @@ choose_next_context() {
|
|
|
|
|
|
|
|
} else {
|
|
} else {
|
|
|
// No threads are ready!
|
|
// 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()) {
|
|
if (!_blocked.empty()) {
|
|
|
thread_cat->error()
|
|
thread_cat->error()
|
|
|
<< "Deadlock! All threads blocked.\n";
|
|
<< "Deadlock! All threads blocked.\n";
|
|
@@ -593,15 +615,6 @@ choose_next_context() {
|
|
|
abort();
|
|
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
|
|
// No threads are queued anywhere. This is some kind of
|
|
|
// internal error, since normally the main thread, at least,
|
|
// internal error, since normally the main thread, at least,
|
|
|
// should be queued somewhere.
|
|
// should be queued somewhere.
|