upon_birth race condition issues

This commit is contained in:
David Rose 2008-10-13 18:24:18 +00:00
parent 22b4a9c3b8
commit 3bd5914b57
9 changed files with 23 additions and 16 deletions

View File

@ -472,9 +472,9 @@ do_task() {
// This function is called with the lock *not* held. // This function is called with the lock *not* held.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AsyncTask:: void AsyncTask::
upon_birth() { upon_birth(AsyncTaskManager *manager) {
// Throw a generic add event for the 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); PT_Event event = new Event(add_name);
event->add_parameter(EventParameter(this)); event->add_parameter(EventParameter(this));
throw_event(event); throw_event(event);

View File

@ -119,7 +119,7 @@ protected:
virtual bool is_runnable(); virtual bool is_runnable();
virtual DoneStatus do_task(); virtual DoneStatus do_task();
virtual void upon_birth(); virtual void upon_birth(AsyncTaskManager *manager);
virtual void upon_death(AsyncTaskManager *manager, bool clean_exit); virtual void upon_death(AsyncTaskManager *manager, bool clean_exit);
protected: protected:

View File

@ -223,6 +223,13 @@ add(AsyncTask *task) {
nassertv(task->_manager == NULL && nassertv(task->_manager == NULL &&
task->_state == AsyncTask::S_inactive); task->_state == AsyncTask::S_inactive);
nassertv(!do_has_task(task)); 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); AsyncTaskChain *chain = do_find_task_chain(task->_chain_name);
if (chain == (AsyncTaskChain *)NULL) { if (chain == (AsyncTaskChain *)NULL) {
@ -233,8 +240,6 @@ add(AsyncTask *task) {
} }
chain->do_add(task); chain->do_add(task);
} }
task->upon_birth();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -132,8 +132,8 @@ do_task() {
// return with it held. // return with it held.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AsyncTaskSequence:: void AsyncTaskSequence::
upon_birth() { upon_birth(AsyncTaskManager *manager) {
AsyncTask::upon_birth(); AsyncTask::upon_birth(manager);
_task_index = 0; _task_index = 0;
set_current_task(NULL, true); 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->_state == S_active_nested);
nassertv(_current_task->_manager == _manager || _manager == NULL); nassertv(_current_task->_manager == _manager || _manager == NULL);
_current_task->_state = S_inactive; _current_task->_state = S_inactive;
_current_task->upon_death(_manager, clean_exit);
_current_task->_manager = NULL; _current_task->_manager = NULL;
_current_task->upon_death(_manager, clean_exit);
} }
_current_task = task; _current_task = task;
if (_current_task != (AsyncTask *)NULL) { 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->_state == S_inactive);
nassertv(_current_task->_manager == NULL); nassertv(_current_task->_manager == NULL);
_current_task->_manager = _manager; _current_task->_manager = _manager;
_current_task->_state = S_active_nested; _current_task->_state = S_active_nested;
_current_task->upon_birth();
} }
} }

View File

@ -48,7 +48,7 @@ PUBLISHED:
protected: protected:
virtual bool is_runnable(); virtual bool is_runnable();
virtual DoneStatus do_task(); virtual DoneStatus do_task();
virtual void upon_birth(); virtual void upon_birth(AsyncTaskManager *manager);
virtual void upon_death(AsyncTaskManager *manager, bool clean_exit); virtual void upon_death(AsyncTaskManager *manager, bool clean_exit);
private: private:

View File

@ -85,8 +85,8 @@ do_task() {
// This function is called with the lock *not* held. // This function is called with the lock *not* held.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void GenericAsyncTask:: void GenericAsyncTask::
upon_birth() { upon_birth(AsyncTaskManager *manager) {
AsyncTask::upon_birth(); AsyncTask::upon_birth(manager);
if (_upon_birth != NULL) { if (_upon_birth != NULL) {
(*_upon_birth)(this, _user_data); (*_upon_birth)(this, _user_data);

View File

@ -50,7 +50,7 @@ public:
protected: protected:
virtual bool is_runnable(); virtual bool is_runnable();
virtual DoneStatus do_task(); virtual DoneStatus do_task();
virtual void upon_birth(); virtual void upon_birth(AsyncTaskManager *manager);
virtual void upon_death(AsyncTaskManager *manager, bool clean_exit); virtual void upon_death(AsyncTaskManager *manager, bool clean_exit);
private: private:

View File

@ -475,8 +475,8 @@ do_python_task() {
// This function is called with the lock *not* held. // This function is called with the lock *not* held.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void PythonTask:: void PythonTask::
upon_birth() { upon_birth(AsyncTaskManager *manager) {
AsyncTask::upon_birth(); AsyncTask::upon_birth(manager);
register_to_owner(); register_to_owner();
} }

View File

@ -51,7 +51,7 @@ protected:
virtual bool is_runnable(); virtual bool is_runnable();
virtual DoneStatus do_task(); virtual DoneStatus do_task();
DoneStatus do_python_task(); DoneStatus do_python_task();
virtual void upon_birth(); virtual void upon_birth(AsyncTaskManager *manager);
virtual void upon_death(AsyncTaskManager *manager, bool clean_exit); virtual void upon_death(AsyncTaskManager *manager, bool clean_exit);
private: private: