From bca1533952ec008f3ae98054fddc139fc653aabe Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 10 Oct 2008 21:30:11 +0000 Subject: [PATCH] interrupt should not stop task --- panda/src/event/asyncTask.cxx | 5 +++-- panda/src/event/asyncTask.h | 14 +++++++------- panda/src/event/asyncTaskChain.cxx | 26 ++++++++++++++------------ panda/src/event/asyncTaskChain.h | 8 ++++---- panda/src/event/asyncTaskSequence.cxx | 2 +- panda/src/event/genericAsyncTask.cxx | 2 +- panda/src/event/pythonTask.cxx | 6 +++--- 7 files changed, 33 insertions(+), 30 deletions(-) diff --git a/panda/src/event/asyncTask.cxx b/panda/src/event/asyncTask.cxx index cb2204618b..7fb00ad451 100644 --- a/panda/src/event/asyncTask.cxx +++ b/panda/src/event/asyncTask.cxx @@ -424,8 +424,9 @@ is_runnable() { // DS_pause: delay the task for set_delay() seconds, // then stop it. This is only useful within a sequence. // -// DS_abort: stop the task, and interrupt the whole -// AsyncTaskManager. +// DS_interrupt: Interrupt the whole AsyncTaskManager. +// The task will continue again next epoch, as if it had +// returned DS_cont. // // This function is called with the lock *not* held. //////////////////////////////////////////////////////////////////// diff --git a/panda/src/event/asyncTask.h b/panda/src/event/asyncTask.h index 3dfa6cb8a4..4dc9b384a8 100644 --- a/panda/src/event/asyncTask.h +++ b/panda/src/event/asyncTask.h @@ -50,13 +50,13 @@ PUBLISHED: virtual ~AsyncTask(); enum DoneStatus { - DS_done, // normal task completion - DS_cont, // run task again next epoch - DS_again, // start the task over from the beginning - DS_pickup, // run task again this frame, if frame budget allows - DS_exit, // stop the enclosing sequence - DS_pause, // pause, then exit (useful within a sequence) - DS_abort, // interrupt the task manager + DS_done, // normal task completion + DS_cont, // run task again next epoch + DS_again, // start the task over from the beginning + DS_pickup, // run task again this frame, if frame budget allows + DS_exit, // stop the enclosing sequence + DS_pause, // pause, then exit (useful within a sequence) + DS_interrupt, // interrupt the task manager, but run task again }; enum State { diff --git a/panda/src/event/asyncTaskChain.cxx b/panda/src/event/asyncTaskChain.cxx index 3eca37c57a..7b9947e782 100644 --- a/panda/src/event/asyncTaskChain.cxx +++ b/panda/src/event/asyncTaskChain.cxx @@ -264,7 +264,7 @@ get_timeslice_priority() const { //////////////////////////////////////////////////////////////////// void AsyncTaskChain:: stop_threads() { - if (_state == S_started || _state == S_aborting) { + if (_state == S_started || _state == S_interrupted) { // Clean up all of the threads. MutexHolder holder(_manager->_lock); do_stop_threads(); @@ -280,7 +280,7 @@ stop_threads() { //////////////////////////////////////////////////////////////////// void AsyncTaskChain:: start_threads() { - if (_state == S_initial || _state == S_aborting) { + if (_state == S_initial || _state == S_interrupted) { MutexHolder holder(_manager->_lock); do_start_threads(); } @@ -563,7 +563,7 @@ do_wait_for_tasks() { if (_threads.empty()) { // Non-threaded case. while (_num_tasks > 0) { - if (_state == S_shutdown || _state == S_aborting) { + if (_state == S_shutdown || _state == S_interrupted) { return; } do_poll(); @@ -572,7 +572,7 @@ do_wait_for_tasks() { } else { // Threaded case. while (_num_tasks > 0) { - if (_state == S_shutdown || _state == S_aborting) { + if (_state == S_shutdown || _state == S_interrupted) { return; } @@ -746,14 +746,16 @@ service_one_task(AsyncTaskChain::AsyncTaskChainThread *thread) { _cvar.signal_all(); break; - case AsyncTask::DS_abort: + case AsyncTask::DS_interrupt: // The task had an exception and wants to raise a big flag. - cleanup_task(task, true, false); + task->_state = AsyncTask::S_active; + _next_active.push_back(task); if (_state == S_started) { - _state = S_aborting; + _state = S_interrupted; _cvar.signal_all(); } break; + default: // The task has finished. @@ -1019,7 +1021,7 @@ filter_timeslice_priority() { //////////////////////////////////////////////////////////////////// void AsyncTaskChain:: do_stop_threads() { - if (_state == S_started || _state == S_aborting) { + if (_state == S_started || _state == S_interrupted) { if (task_cat.is_debug() && !_threads.empty()) { task_cat.debug() << "Stopping " << _threads.size() @@ -1062,7 +1064,7 @@ do_stop_threads() { //////////////////////////////////////////////////////////////////// void AsyncTaskChain:: do_start_threads() { - if (_state == S_aborting) { + if (_state == S_interrupted) { do_stop_threads(); } @@ -1166,7 +1168,7 @@ do_poll() { do { while (!_active.empty()) { - if (_state == S_shutdown || _state == S_aborting) { + if (_state == S_shutdown || _state == S_interrupted) { return; } int frame = _manager->_clock->get_frame_count(); @@ -1405,7 +1407,7 @@ AsyncTaskChainThread(const string &name, AsyncTaskChain *chain) : void AsyncTaskChain::AsyncTaskChainThread:: thread_main() { MutexHolder holder(_chain->_manager->_lock); - while (_chain->_state != S_shutdown && _chain->_state != S_aborting) { + while (_chain->_state != S_shutdown && _chain->_state != S_interrupted) { thread_consider_yield(); if (!_chain->_active.empty() && _chain->_active.front()->get_sort() == _chain->_current_sort) { @@ -1420,7 +1422,7 @@ thread_main() { // frame. if (_chain->_frame_budget >= 0.0 && _chain->_time_in_frame >= _chain->_frame_budget) { while (_chain->_frame_budget >= 0.0 && _chain->_time_in_frame >= _chain->_frame_budget && - _chain->_state != S_shutdown && _chain->_state != S_aborting) { + _chain->_state != S_shutdown && _chain->_state != S_interrupted) { _chain->cleanup_pickup_mode(); _chain->_manager->_frame_cvar.wait(); frame = _chain->_manager->_clock->get_frame_count(); diff --git a/panda/src/event/asyncTaskChain.h b/panda/src/event/asyncTaskChain.h index 74c38420aa..97c17a615a 100644 --- a/panda/src/event/asyncTaskChain.h +++ b/panda/src/event/asyncTaskChain.h @@ -160,10 +160,10 @@ protected: ConditionVarFull _cvar; // signaled when one of the task heaps, _state, or _current_sort changes, or a task finishes. enum State { - S_initial, // no threads yet - S_started, // threads have been started - S_aborting, // task returned DS_abort, shutdown requested from sub-thread. - S_shutdown // waiting for thread shutdown, requested from main thread + S_initial, // no threads yet + S_started, // threads have been started + S_interrupted, // task returned DS_interrupt, requested from sub-thread. + S_shutdown // waiting for thread shutdown, requested from main thread }; bool _tick_clock; diff --git a/panda/src/event/asyncTaskSequence.cxx b/panda/src/event/asyncTaskSequence.cxx index 75b23a62da..99a6397fda 100644 --- a/panda/src/event/asyncTaskSequence.cxx +++ b/panda/src/event/asyncTaskSequence.cxx @@ -115,7 +115,7 @@ do_task() { case DS_cont: case DS_pickup: case DS_exit: - case DS_abort: + case DS_interrupt: // Just return these results through. return result; } diff --git a/panda/src/event/genericAsyncTask.cxx b/panda/src/event/genericAsyncTask.cxx index adc21c176f..f39d196694 100644 --- a/panda/src/event/genericAsyncTask.cxx +++ b/panda/src/event/genericAsyncTask.cxx @@ -72,7 +72,7 @@ is_runnable() { //////////////////////////////////////////////////////////////////// AsyncTask::DoneStatus GenericAsyncTask:: do_task() { - nassertr(_function != NULL, DS_abort); + nassertr(_function != NULL, DS_interrupt); return (*_function)(this, _user_data); } diff --git a/panda/src/event/pythonTask.cxx b/panda/src/event/pythonTask.cxx index 55328c0b4f..c27f0f0140 100644 --- a/panda/src/event/pythonTask.cxx +++ b/panda/src/event/pythonTask.cxx @@ -400,7 +400,7 @@ do_python_task() { if (_generator != (PyObject *)NULL) { // We are calling a generator. PyObject *func = PyObject_GetAttrString(_generator, "next"); - nassertr(func != (PyObject *)NULL, DS_abort); + nassertr(func != (PyObject *)NULL, DS_interrupt); result = PyObject_CallObject(func, NULL); Py_DECREF(func); @@ -418,7 +418,7 @@ do_python_task() { if (result == (PyObject *)NULL) { task_cat.error() << "Exception occurred in " << *this << "\n"; - return DS_abort; + return DS_interrupt; } if (result == Py_None) { @@ -463,7 +463,7 @@ do_python_task() { string message = strm.str(); nassert_raise(message); - return DS_abort; + return DS_interrupt; } ////////////////////////////////////////////////////////////////////