Fixed a crash in the Event Manager when a game fired an event from a listener that was looking for the same event (bug 3468, r=me).
In other words it was a problem where our FireEvent hooks were being re-entered for the _same_ game event. The Event Manager was not able to handle this and crashed.
This commit is contained in:
parent
a8e1a4f2fd
commit
7167a807bf
@ -377,21 +377,21 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
|
|
||||||
if (pForward)
|
if (pForward)
|
||||||
{
|
{
|
||||||
EventInfo info = { pEvent, NULL };
|
EventInfo info(pEvent, NULL);
|
||||||
|
HandleSecurity sec(NULL, g_pCoreIdent);
|
||||||
Handle_t hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
|
Handle_t hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
|
||||||
|
|
||||||
pForward->PushCell(hndl);
|
pForward->PushCell(hndl);
|
||||||
pForward->PushString(name);
|
pForward->PushString(name);
|
||||||
pForward->PushCell(bDontBroadcast);
|
pForward->PushCell(bDontBroadcast);
|
||||||
pForward->Execute(&res, NULL);
|
pForward->Execute(&res, NULL);
|
||||||
|
|
||||||
HandleSecurity sec(NULL, g_pCoreIdent);
|
|
||||||
g_HandleSys.FreeHandle(hndl, &sec);
|
g_HandleSys.FreeHandle(hndl, &sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pHook->postCopy)
|
if (pHook->postCopy)
|
||||||
{
|
{
|
||||||
pHook->pEventCopy = gameevents->DuplicateEvent(pEvent);
|
m_EventCopies.push(gameevents->DuplicateEvent(pEvent));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
@ -407,8 +407,8 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
/* IGameEventManager2::FireEvent post hook */
|
/* IGameEventManager2::FireEvent post hook */
|
||||||
bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
|
bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
|
||||||
{
|
{
|
||||||
IGameEvent *pEventCopy = NULL;
|
|
||||||
EventHook *pHook;
|
EventHook *pHook;
|
||||||
|
EventInfo info;
|
||||||
IChangeableForward *pForward;
|
IChangeableForward *pForward;
|
||||||
const char *name;
|
const char *name;
|
||||||
Handle_t hndl = 0;
|
Handle_t hndl = 0;
|
||||||
@ -424,14 +424,13 @@ bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
if (sm_trie_retrieve(m_EventHooks, name, reinterpret_cast<void **>(&pHook)))
|
if (sm_trie_retrieve(m_EventHooks, name, reinterpret_cast<void **>(&pHook)))
|
||||||
{
|
{
|
||||||
pForward = pHook->pPostHook;
|
pForward = pHook->pPostHook;
|
||||||
pEventCopy = pHook->pEventCopy;
|
|
||||||
|
|
||||||
if (pForward)
|
if (pForward)
|
||||||
{
|
{
|
||||||
EventInfo info = { pEventCopy, NULL };
|
|
||||||
|
|
||||||
if (pHook->postCopy)
|
if (pHook->postCopy)
|
||||||
{
|
{
|
||||||
|
info.pEvent = m_EventCopies.front();
|
||||||
|
info.pOwner = NULL;
|
||||||
hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
|
hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
|
||||||
|
|
||||||
pForward->PushCell(hndl);
|
pForward->PushCell(hndl);
|
||||||
@ -450,8 +449,8 @@ bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
g_HandleSys.FreeHandle(hndl, &sec);
|
g_HandleSys.FreeHandle(hndl, &sec);
|
||||||
|
|
||||||
/* Free event structure */
|
/* Free event structure */
|
||||||
gameevents->FreeEvent(pEventCopy);
|
gameevents->FreeEvent(info.pEvent);
|
||||||
pHook->pEventCopy = NULL;
|
m_EventCopies.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,12 @@ using namespace SourceHook;
|
|||||||
|
|
||||||
struct EventInfo
|
struct EventInfo
|
||||||
{
|
{
|
||||||
|
EventInfo()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
EventInfo(IGameEvent *ev, IdentityToken_t *owner) : pEvent(ev), pOwner(owner)
|
||||||
|
{
|
||||||
|
}
|
||||||
IGameEvent *pEvent;
|
IGameEvent *pEvent;
|
||||||
IdentityToken_t *pOwner;
|
IdentityToken_t *pOwner;
|
||||||
};
|
};
|
||||||
@ -56,13 +62,11 @@ struct EventHook
|
|||||||
pPreHook = NULL;
|
pPreHook = NULL;
|
||||||
pPostHook = NULL;
|
pPostHook = NULL;
|
||||||
postCopy = false;
|
postCopy = false;
|
||||||
pEventCopy = NULL;
|
|
||||||
refCount = 0;
|
refCount = 0;
|
||||||
}
|
}
|
||||||
IChangeableForward *pPreHook;
|
IChangeableForward *pPreHook;
|
||||||
IChangeableForward *pPostHook;
|
IChangeableForward *pPostHook;
|
||||||
bool postCopy;
|
bool postCopy;
|
||||||
IGameEvent *pEventCopy;
|
|
||||||
unsigned int refCount;
|
unsigned int refCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -121,6 +125,7 @@ private:
|
|||||||
Trie *m_EventHooks;
|
Trie *m_EventHooks;
|
||||||
CStack<EventInfo *> m_FreeEvents;
|
CStack<EventInfo *> m_FreeEvents;
|
||||||
CStack<const char *> m_EventNames;
|
CStack<const char *> m_EventNames;
|
||||||
|
CStack<IGameEvent *> m_EventCopies;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern EventManager g_EventManager;
|
extern EventManager g_EventManager;
|
||||||
|
Loading…
Reference in New Issue
Block a user