From 3bd5914b575c59d61101a11eb0b0643e64ab4b24 Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 13 Oct 2008 18:24:18 +0000 Subject: [PATCH] upon_birth race condition issues --- panda/src/event/asyncTask.cxx | 4 ++-- panda/src/event/asyncTask.h | 2 +- panda/src/event/asyncTaskManager.cxx | 9 +++++++-- panda/src/event/asyncTaskSequence.cxx | 10 ++++++---- panda/src/event/asyncTaskSequence.h | 2 +- panda/src/event/genericAsyncTask.cxx | 4 ++-- panda/src/event/genericAsyncTask.h | 2 +- panda/src/event/pythonTask.cxx | 4 ++-- panda/src/event/pythonTask.h | 2 +- 9 files changed, 23 insertions(+), 16 deletions(-) diff --git a/panda/src/event/asyncTask.cxx b/panda/src/event/asyncTask.cxx index a06746a50b..058bc4f553 100644 --- a/panda/src/event/asyncTask.cxx +++ b/panda/src/event/asyncTask.cxx @@ -472,9 +472,9 @@ do_task() { // This function is called with the lock *not* held. //////////////////////////////////////////////////////////////////// void AsyncTask:: -upon_birth() { +upon_birth(AsyncTaskManager *manager) { // Throw a generic add event for the manager. - string add_name = _manager->get_name() + "-addTask"; + string add_name = manager->get_name() + "-addTask"; PT_Event event = new Event(add_name); event->add_parameter(EventParameter(this)); throw_event(event); diff --git a/panda/src/event/asyncTask.h b/panda/src/event/asyncTask.h index aa284b3273..f39e7e0ef1 100644 --- a/panda/src/event/asyncTask.h +++ b/panda/src/event/asyncTask.h @@ -119,7 +119,7 @@ protected: virtual bool is_runnable(); virtual DoneStatus do_task(); - virtual void upon_birth(); + virtual void upon_birth(AsyncTaskManager *manager); virtual void upon_death(AsyncTaskManager *manager, bool clean_exit); protected: diff --git a/panda/src/event/asyncTaskManager.cxx b/panda/src/event/asyncTaskManager.cxx index af96fd65f3..cdb3de2840 100644 --- a/panda/src/event/asyncTaskManager.cxx +++ b/panda/src/event/asyncTaskManager.cxx @@ -223,6 +223,13 @@ add(AsyncTask *task) { nassertv(task->_manager == NULL && task->_state == AsyncTask::S_inactive); nassertv(!do_has_task(task)); + + _lock.release(); + task->upon_birth(this); + _lock.lock(); + nassertv(task->_manager == NULL && + task->_state == AsyncTask::S_inactive); + nassertv(!do_has_task(task)); AsyncTaskChain *chain = do_find_task_chain(task->_chain_name); if (chain == (AsyncTaskChain *)NULL) { @@ -233,8 +240,6 @@ add(AsyncTask *task) { } chain->do_add(task); } - - task->upon_birth(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/event/asyncTaskSequence.cxx b/panda/src/event/asyncTaskSequence.cxx index 9d567da5a8..90ccbcca49 100644 --- a/panda/src/event/asyncTaskSequence.cxx +++ b/panda/src/event/asyncTaskSequence.cxx @@ -132,8 +132,8 @@ do_task() { // return with it held. //////////////////////////////////////////////////////////////////// void AsyncTaskSequence:: -upon_birth() { - AsyncTask::upon_birth(); +upon_birth(AsyncTaskManager *manager) { + AsyncTask::upon_birth(manager); _task_index = 0; set_current_task(NULL, true); } @@ -180,17 +180,19 @@ set_current_task(AsyncTask *task, bool clean_exit) { nassertv(_current_task->_state == S_active_nested); nassertv(_current_task->_manager == _manager || _manager == NULL); _current_task->_state = S_inactive; - _current_task->upon_death(_manager, clean_exit); _current_task->_manager = NULL; + _current_task->upon_death(_manager, clean_exit); } _current_task = task; if (_current_task != (AsyncTask *)NULL) { + nassertv(_current_task->_state == S_inactive); + nassertv(_current_task->_manager == NULL); + _current_task->upon_birth(_manager); nassertv(_current_task->_state == S_inactive); nassertv(_current_task->_manager == NULL); _current_task->_manager = _manager; _current_task->_state = S_active_nested; - _current_task->upon_birth(); } } diff --git a/panda/src/event/asyncTaskSequence.h b/panda/src/event/asyncTaskSequence.h index 66f813c6bf..09285aa961 100644 --- a/panda/src/event/asyncTaskSequence.h +++ b/panda/src/event/asyncTaskSequence.h @@ -48,7 +48,7 @@ PUBLISHED: protected: virtual bool is_runnable(); virtual DoneStatus do_task(); - virtual void upon_birth(); + virtual void upon_birth(AsyncTaskManager *manager); virtual void upon_death(AsyncTaskManager *manager, bool clean_exit); private: diff --git a/panda/src/event/genericAsyncTask.cxx b/panda/src/event/genericAsyncTask.cxx index dd198aa652..0b85504360 100644 --- a/panda/src/event/genericAsyncTask.cxx +++ b/panda/src/event/genericAsyncTask.cxx @@ -85,8 +85,8 @@ do_task() { // This function is called with the lock *not* held. //////////////////////////////////////////////////////////////////// void GenericAsyncTask:: -upon_birth() { - AsyncTask::upon_birth(); +upon_birth(AsyncTaskManager *manager) { + AsyncTask::upon_birth(manager); if (_upon_birth != NULL) { (*_upon_birth)(this, _user_data); diff --git a/panda/src/event/genericAsyncTask.h b/panda/src/event/genericAsyncTask.h index d6cd94b45c..4ce3f351ab 100644 --- a/panda/src/event/genericAsyncTask.h +++ b/panda/src/event/genericAsyncTask.h @@ -50,7 +50,7 @@ public: protected: virtual bool is_runnable(); virtual DoneStatus do_task(); - virtual void upon_birth(); + virtual void upon_birth(AsyncTaskManager *manager); virtual void upon_death(AsyncTaskManager *manager, bool clean_exit); private: diff --git a/panda/src/event/pythonTask.cxx b/panda/src/event/pythonTask.cxx index 114073fcb3..dd9b27f3fd 100644 --- a/panda/src/event/pythonTask.cxx +++ b/panda/src/event/pythonTask.cxx @@ -475,8 +475,8 @@ do_python_task() { // This function is called with the lock *not* held. //////////////////////////////////////////////////////////////////// void PythonTask:: -upon_birth() { - AsyncTask::upon_birth(); +upon_birth(AsyncTaskManager *manager) { + AsyncTask::upon_birth(manager); register_to_owner(); } diff --git a/panda/src/event/pythonTask.h b/panda/src/event/pythonTask.h index f29bcd016d..6f087e7d59 100644 --- a/panda/src/event/pythonTask.h +++ b/panda/src/event/pythonTask.h @@ -51,7 +51,7 @@ protected: virtual bool is_runnable(); virtual DoneStatus do_task(); DoneStatus do_python_task(); - virtual void upon_birth(); + virtual void upon_birth(AsyncTaskManager *manager); virtual void upon_death(AsyncTaskManager *manager, bool clean_exit); private: