Dont enter AIStateMachine::multiplex recursively.

This commit is contained in:
Aleric Inglewood
2013-03-08 16:58:25 +01:00
parent 933ca23348
commit 50caf98cd6
2 changed files with 11 additions and 4 deletions

View File

@@ -400,6 +400,7 @@ void AIStateMachine::multiplex(event_type event)
// If another thread is already running multiplex() then it will pick up // If another thread is already running multiplex() then it will pick up
// our need to run (by us having set need_run), so there is no need to run // our need to run (by us having set need_run), so there is no need to run
// ourselves. // ourselves.
llassert(!mMultiplexMutex.isSelfLocked()); // We may never enter recursively!
if (!mMultiplexMutex.tryLock()) if (!mMultiplexMutex.tryLock())
{ {
Dout(dc::statemachine, "Leaving because it is already being run [" << (void*)this << "]"); Dout(dc::statemachine, "Leaving because it is already being run [" << (void*)this << "]");
@@ -999,7 +1000,10 @@ void AIStateMachine::advance_state(state_type new_state)
mDebugAdvanceStatePending = true; mDebugAdvanceStatePending = true;
#endif #endif
} }
multiplex(schedule_run); if (!mMultiplexMutex.isSelfLocked())
{
multiplex(schedule_run);
}
} }
void AIStateMachine::idle(void) void AIStateMachine::idle(void)
@@ -1045,7 +1049,10 @@ void AIStateMachine::cont(void)
mDebugContPending = true; mDebugContPending = true;
#endif #endif
} }
multiplex(schedule_run); if (!mMultiplexMutex.isSelfLocked())
{
multiplex(schedule_run);
}
} }
void AIStateMachine::abort(void) void AIStateMachine::abort(void)
@@ -1062,7 +1069,7 @@ void AIStateMachine::abort(void)
// Schedule a new run when this state machine is waiting. // Schedule a new run when this state machine is waiting.
is_waiting = state_r->base_state == bs_multiplex && sub_state_w->idle; is_waiting = state_r->base_state == bs_multiplex && sub_state_w->idle;
} }
if (is_waiting) if (is_waiting && !mMultiplexMutex.isSelfLocked())
{ {
multiplex(insert_abort); multiplex(insert_abort);
} }

View File

@@ -197,7 +197,7 @@ class AIStateMachine : public LLThreadSafeRefCount
public: public:
AIStateMachine(void) : mCallback(NULL), mDefaultEngine(NULL), mYieldEngine(NULL), AIStateMachine(void) : mCallback(NULL), mDefaultEngine(NULL), mYieldEngine(NULL),
#ifdef SHOW_ASSERT #ifdef SHOW_ASSERT
mDebugLastState(bs_killed), mDebugShouldRun(false), mDebugAborted(false), mDebugContPending(false), mThreadId(AIThreadID::none), mDebugLastState(bs_killed), mDebugShouldRun(false), mDebugAborted(false), mDebugContPending(false),
mDebugSetStatePending(false), mDebugAdvanceStatePending(false), mDebugRefCalled(false), mDebugSetStatePending(false), mDebugAdvanceStatePending(false), mDebugRefCalled(false),
#endif #endif
mRuntime(0) mRuntime(0)