Skip to content

Commit

Permalink
xrGame: deferred addition/removing in set_fastcall. Fix double free.
Browse files Browse the repository at this point in the history
  • Loading branch information
vamit611 committed Jan 31, 2019
1 parent bc635a1 commit 2ea57b5
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/xrGame/Level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ void CLevel::OnFrame()
if (!GEnv.isDedicatedServer)
GEnv.ScriptEngine->script_process(ScriptProcessor::Level)->update();
m_ph_commander->update();
m_ph_commander_scripts->UpdateDeferred();
m_ph_commander_scripts->update();
stats.BulletManagerCommit.Begin();
BulletManager().CommitRenderSet();
Expand Down
39 changes: 39 additions & 0 deletions src/xrGame/PHCommander.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,29 @@ void CPHCommander::clear()
delete_call(it);

m_calls.clear();
m_callsUpdateDeferred.clear();
}

void CPHCommander::UpdateDeferred()
{
for (auto it : m_callsUpdateDeferred)
{
if (it.second)
{
m_calls.push_back(it.first);
}
else
{
auto callToDeleteIt = std::find(m_calls.begin(), m_calls.end(), it.first);
if (callToDeleteIt != m_calls.end())
{
delete_call(*callToDeleteIt);
m_calls.erase(callToDeleteIt);
}
}
}

m_callsUpdateDeferred.clear();
}

void CPHCommander::update()
Expand Down Expand Up @@ -93,6 +116,11 @@ void CPHCommander::add_call(CPHCondition* condition, CPHAction* action)
m_calls.push_back(new CPHCall(condition, action));
}

void CPHCommander::AddCallDeferred(CPHCondition* condition, CPHAction* action)
{
m_callsUpdateDeferred.insert({new CPHCall(condition, action), true});
}

struct SFEqualPred
{
CPHReqComparerV *cmp_condition, *cmp_action;
Expand Down Expand Up @@ -177,6 +205,17 @@ void CPHCommander::remove_calls(CPHReqComparerV* cmp_object)
m_calls.erase(std::remove_if(m_calls.begin(), m_calls.end(), SRemovePred1(cmp_object)), m_calls.end());
}

void CPHCommander::RemoveCallsDeferred(CPHReqComparerV* comparer)
{
for (const auto& call : m_calls)
{
if (call->is_any(comparer))
{
m_callsUpdateDeferred.insert({call, false});
}
}
}

void CPHCommander::phys_shell_relcase(CPhysicsShell* sh)
{
CPHReqComparerHasShell c(sh);
Expand Down
4 changes: 4 additions & 0 deletions src/xrGame/PHCommander.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class CPHCommander : public IPHWorldUpdateCallbck
{
Lock lock;
PHCALL_STORAGE m_calls;
xr_unordered_map<CPHCall*, bool> m_callsUpdateDeferred;

public:
~CPHCommander();
Expand All @@ -82,13 +83,16 @@ class CPHCommander : public IPHWorldUpdateCallbck
CPHCondition* condition, CPHReqComparerV* cmp_condition, CPHAction* action, CPHReqComparerV* cmp_action);
void add_call(CPHCondition* condition, CPHAction* action);
void add_call_threadsafety(CPHCondition* condition, CPHAction* action);
void AddCallDeferred(CPHCondition* condition, CPHAction* action);

bool has_call(CPHReqComparerV* cmp_condition, CPHReqComparerV* cmp_action);
PHCALL_I find_call(CPHReqComparerV* cmp_condition, CPHReqComparerV* cmp_action);
void remove_call(CPHReqComparerV* cmp_condition, CPHReqComparerV* cmp_action);
void remove_calls(CPHReqComparerV* cmp_object);
void remove_calls_threadsafety(CPHReqComparerV* cmp_object);
void RemoveCallsDeferred(CPHReqComparerV* comparer);

void UpdateDeferred();
void update();
void update_threadsafety();

Expand Down
4 changes: 2 additions & 2 deletions src/xrGame/script_game_object_use.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ void CScriptGameObject::set_fastcall(const luabind::functor<bool>& functor, cons
CPHScriptGameObjectCondition* c = new CPHScriptGameObjectCondition(object, functor, m_game_object);
CPHDummiAction* a = new CPHDummiAction();
CPHSriptReqGObjComparer cmpr(m_game_object);
Level().ph_commander_scripts().remove_calls(&cmpr);
Level().ph_commander_scripts().add_call(c, a);
Level().ph_commander_scripts().RemoveCallsDeferred(&cmpr);
Level().ph_commander_scripts().AddCallDeferred(c, a);
}
void CScriptGameObject::set_const_force(const Fvector& dir, float value, u32 time_interval)
{
Expand Down

0 comments on commit 2ea57b5

Please sign in to comment.