mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
interrupt should not stop task
This commit is contained in:
parent
7f9a509f04
commit
bca1533952
@ -424,8 +424,9 @@ is_runnable() {
|
|||||||
// DS_pause: delay the task for set_delay() seconds,
|
// DS_pause: delay the task for set_delay() seconds,
|
||||||
// then stop it. This is only useful within a sequence.
|
// then stop it. This is only useful within a sequence.
|
||||||
//
|
//
|
||||||
// DS_abort: stop the task, and interrupt the whole
|
// DS_interrupt: Interrupt the whole AsyncTaskManager.
|
||||||
// AsyncTaskManager.
|
// The task will continue again next epoch, as if it had
|
||||||
|
// returned DS_cont.
|
||||||
//
|
//
|
||||||
// This function is called with the lock *not* held.
|
// This function is called with the lock *not* held.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -50,13 +50,13 @@ PUBLISHED:
|
|||||||
virtual ~AsyncTask();
|
virtual ~AsyncTask();
|
||||||
|
|
||||||
enum DoneStatus {
|
enum DoneStatus {
|
||||||
DS_done, // normal task completion
|
DS_done, // normal task completion
|
||||||
DS_cont, // run task again next epoch
|
DS_cont, // run task again next epoch
|
||||||
DS_again, // start the task over from the beginning
|
DS_again, // start the task over from the beginning
|
||||||
DS_pickup, // run task again this frame, if frame budget allows
|
DS_pickup, // run task again this frame, if frame budget allows
|
||||||
DS_exit, // stop the enclosing sequence
|
DS_exit, // stop the enclosing sequence
|
||||||
DS_pause, // pause, then exit (useful within a sequence)
|
DS_pause, // pause, then exit (useful within a sequence)
|
||||||
DS_abort, // interrupt the task manager
|
DS_interrupt, // interrupt the task manager, but run task again
|
||||||
};
|
};
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
|
@ -264,7 +264,7 @@ get_timeslice_priority() const {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void AsyncTaskChain::
|
void AsyncTaskChain::
|
||||||
stop_threads() {
|
stop_threads() {
|
||||||
if (_state == S_started || _state == S_aborting) {
|
if (_state == S_started || _state == S_interrupted) {
|
||||||
// Clean up all of the threads.
|
// Clean up all of the threads.
|
||||||
MutexHolder holder(_manager->_lock);
|
MutexHolder holder(_manager->_lock);
|
||||||
do_stop_threads();
|
do_stop_threads();
|
||||||
@ -280,7 +280,7 @@ stop_threads() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void AsyncTaskChain::
|
void AsyncTaskChain::
|
||||||
start_threads() {
|
start_threads() {
|
||||||
if (_state == S_initial || _state == S_aborting) {
|
if (_state == S_initial || _state == S_interrupted) {
|
||||||
MutexHolder holder(_manager->_lock);
|
MutexHolder holder(_manager->_lock);
|
||||||
do_start_threads();
|
do_start_threads();
|
||||||
}
|
}
|
||||||
@ -563,7 +563,7 @@ do_wait_for_tasks() {
|
|||||||
if (_threads.empty()) {
|
if (_threads.empty()) {
|
||||||
// Non-threaded case.
|
// Non-threaded case.
|
||||||
while (_num_tasks > 0) {
|
while (_num_tasks > 0) {
|
||||||
if (_state == S_shutdown || _state == S_aborting) {
|
if (_state == S_shutdown || _state == S_interrupted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
do_poll();
|
do_poll();
|
||||||
@ -572,7 +572,7 @@ do_wait_for_tasks() {
|
|||||||
} else {
|
} else {
|
||||||
// Threaded case.
|
// Threaded case.
|
||||||
while (_num_tasks > 0) {
|
while (_num_tasks > 0) {
|
||||||
if (_state == S_shutdown || _state == S_aborting) {
|
if (_state == S_shutdown || _state == S_interrupted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -746,14 +746,16 @@ service_one_task(AsyncTaskChain::AsyncTaskChainThread *thread) {
|
|||||||
_cvar.signal_all();
|
_cvar.signal_all();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AsyncTask::DS_abort:
|
case AsyncTask::DS_interrupt:
|
||||||
// The task had an exception and wants to raise a big flag.
|
// 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) {
|
if (_state == S_started) {
|
||||||
_state = S_aborting;
|
_state = S_interrupted;
|
||||||
_cvar.signal_all();
|
_cvar.signal_all();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// The task has finished.
|
// The task has finished.
|
||||||
@ -1019,7 +1021,7 @@ filter_timeslice_priority() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void AsyncTaskChain::
|
void AsyncTaskChain::
|
||||||
do_stop_threads() {
|
do_stop_threads() {
|
||||||
if (_state == S_started || _state == S_aborting) {
|
if (_state == S_started || _state == S_interrupted) {
|
||||||
if (task_cat.is_debug() && !_threads.empty()) {
|
if (task_cat.is_debug() && !_threads.empty()) {
|
||||||
task_cat.debug()
|
task_cat.debug()
|
||||||
<< "Stopping " << _threads.size()
|
<< "Stopping " << _threads.size()
|
||||||
@ -1062,7 +1064,7 @@ do_stop_threads() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void AsyncTaskChain::
|
void AsyncTaskChain::
|
||||||
do_start_threads() {
|
do_start_threads() {
|
||||||
if (_state == S_aborting) {
|
if (_state == S_interrupted) {
|
||||||
do_stop_threads();
|
do_stop_threads();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1166,7 +1168,7 @@ do_poll() {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
while (!_active.empty()) {
|
while (!_active.empty()) {
|
||||||
if (_state == S_shutdown || _state == S_aborting) {
|
if (_state == S_shutdown || _state == S_interrupted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int frame = _manager->_clock->get_frame_count();
|
int frame = _manager->_clock->get_frame_count();
|
||||||
@ -1405,7 +1407,7 @@ AsyncTaskChainThread(const string &name, AsyncTaskChain *chain) :
|
|||||||
void AsyncTaskChain::AsyncTaskChainThread::
|
void AsyncTaskChain::AsyncTaskChainThread::
|
||||||
thread_main() {
|
thread_main() {
|
||||||
MutexHolder holder(_chain->_manager->_lock);
|
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();
|
thread_consider_yield();
|
||||||
if (!_chain->_active.empty() &&
|
if (!_chain->_active.empty() &&
|
||||||
_chain->_active.front()->get_sort() == _chain->_current_sort) {
|
_chain->_active.front()->get_sort() == _chain->_current_sort) {
|
||||||
@ -1420,7 +1422,7 @@ thread_main() {
|
|||||||
// frame.
|
// frame.
|
||||||
if (_chain->_frame_budget >= 0.0 && _chain->_time_in_frame >= _chain->_frame_budget) {
|
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 &&
|
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->cleanup_pickup_mode();
|
||||||
_chain->_manager->_frame_cvar.wait();
|
_chain->_manager->_frame_cvar.wait();
|
||||||
frame = _chain->_manager->_clock->get_frame_count();
|
frame = _chain->_manager->_clock->get_frame_count();
|
||||||
|
@ -160,10 +160,10 @@ protected:
|
|||||||
ConditionVarFull _cvar; // signaled when one of the task heaps, _state, or _current_sort changes, or a task finishes.
|
ConditionVarFull _cvar; // signaled when one of the task heaps, _state, or _current_sort changes, or a task finishes.
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
S_initial, // no threads yet
|
S_initial, // no threads yet
|
||||||
S_started, // threads have been started
|
S_started, // threads have been started
|
||||||
S_aborting, // task returned DS_abort, shutdown requested from sub-thread.
|
S_interrupted, // task returned DS_interrupt, requested from sub-thread.
|
||||||
S_shutdown // waiting for thread shutdown, requested from main thread
|
S_shutdown // waiting for thread shutdown, requested from main thread
|
||||||
};
|
};
|
||||||
|
|
||||||
bool _tick_clock;
|
bool _tick_clock;
|
||||||
|
@ -115,7 +115,7 @@ do_task() {
|
|||||||
case DS_cont:
|
case DS_cont:
|
||||||
case DS_pickup:
|
case DS_pickup:
|
||||||
case DS_exit:
|
case DS_exit:
|
||||||
case DS_abort:
|
case DS_interrupt:
|
||||||
// Just return these results through.
|
// Just return these results through.
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ is_runnable() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
AsyncTask::DoneStatus GenericAsyncTask::
|
AsyncTask::DoneStatus GenericAsyncTask::
|
||||||
do_task() {
|
do_task() {
|
||||||
nassertr(_function != NULL, DS_abort);
|
nassertr(_function != NULL, DS_interrupt);
|
||||||
return (*_function)(this, _user_data);
|
return (*_function)(this, _user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,7 +400,7 @@ do_python_task() {
|
|||||||
if (_generator != (PyObject *)NULL) {
|
if (_generator != (PyObject *)NULL) {
|
||||||
// We are calling a generator.
|
// We are calling a generator.
|
||||||
PyObject *func = PyObject_GetAttrString(_generator, "next");
|
PyObject *func = PyObject_GetAttrString(_generator, "next");
|
||||||
nassertr(func != (PyObject *)NULL, DS_abort);
|
nassertr(func != (PyObject *)NULL, DS_interrupt);
|
||||||
|
|
||||||
result = PyObject_CallObject(func, NULL);
|
result = PyObject_CallObject(func, NULL);
|
||||||
Py_DECREF(func);
|
Py_DECREF(func);
|
||||||
@ -418,7 +418,7 @@ do_python_task() {
|
|||||||
if (result == (PyObject *)NULL) {
|
if (result == (PyObject *)NULL) {
|
||||||
task_cat.error()
|
task_cat.error()
|
||||||
<< "Exception occurred in " << *this << "\n";
|
<< "Exception occurred in " << *this << "\n";
|
||||||
return DS_abort;
|
return DS_interrupt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == Py_None) {
|
if (result == Py_None) {
|
||||||
@ -463,7 +463,7 @@ do_python_task() {
|
|||||||
string message = strm.str();
|
string message = strm.str();
|
||||||
nassert_raise(message);
|
nassert_raise(message);
|
||||||
|
|
||||||
return DS_abort;
|
return DS_interrupt;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
x
Reference in New Issue
Block a user