Browse Source

interrupt should not stop task

David Rose 17 years ago
parent
commit
bca1533952

+ 3 - 2
panda/src/event/asyncTask.cxx

@@ -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
-//               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.
 //               This function is called with the lock *not* held.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 7 - 7
panda/src/event/asyncTask.h

@@ -50,13 +50,13 @@ PUBLISHED:
   virtual ~AsyncTask();
   virtual ~AsyncTask();
 
 
   enum DoneStatus {
   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 {
   enum State {

+ 14 - 12
panda/src/event/asyncTaskChain.cxx

@@ -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();

+ 4 - 4
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.
   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_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;
   bool _tick_clock;

+ 1 - 1
panda/src/event/asyncTaskSequence.cxx

@@ -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;
   }
   }

+ 1 - 1
panda/src/event/genericAsyncTask.cxx

@@ -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);
 }
 }
 
 

+ 3 - 3
panda/src/event/pythonTask.cxx

@@ -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;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////