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).
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.
1.1 --- a/core/EventManager.cpp Mon Jan 12 02:33:03 2009 -0500
1.2 +++ b/core/EventManager.cpp Tue Jan 27 23:53:48 2009 -0600
1.3 @@ -377,21 +377,21 @@
1.4
1.5 if (pForward)
1.6 {
1.7 - EventInfo info = { pEvent, NULL };
1.8 + EventInfo info(pEvent, NULL);
1.9 + HandleSecurity sec(NULL, g_pCoreIdent);
1.10 + Handle_t hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
1.11
1.12 - Handle_t hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
1.13 pForward->PushCell(hndl);
1.14 pForward->PushString(name);
1.15 pForward->PushCell(bDontBroadcast);
1.16 pForward->Execute(&res, NULL);
1.17
1.18 - HandleSecurity sec(NULL, g_pCoreIdent);
1.19 g_HandleSys.FreeHandle(hndl, &sec);
1.20 }
1.21
1.22 if (pHook->postCopy)
1.23 {
1.24 - pHook->pEventCopy = gameevents->DuplicateEvent(pEvent);
1.25 + m_EventCopies.push(gameevents->DuplicateEvent(pEvent));
1.26 }
1.27
1.28 if (res)
1.29 @@ -407,8 +407,8 @@
1.30 /* IGameEventManager2::FireEvent post hook */
1.31 bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
1.32 {
1.33 - IGameEvent *pEventCopy = NULL;
1.34 EventHook *pHook;
1.35 + EventInfo info;
1.36 IChangeableForward *pForward;
1.37 const char *name;
1.38 Handle_t hndl = 0;
1.39 @@ -424,14 +424,13 @@
1.40 if (sm_trie_retrieve(m_EventHooks, name, reinterpret_cast<void **>(&pHook)))
1.41 {
1.42 pForward = pHook->pPostHook;
1.43 - pEventCopy = pHook->pEventCopy;
1.44
1.45 if (pForward)
1.46 {
1.47 - EventInfo info = { pEventCopy, NULL };
1.48 -
1.49 if (pHook->postCopy)
1.50 {
1.51 + info.pEvent = m_EventCopies.front();
1.52 + info.pOwner = NULL;
1.53 hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
1.54
1.55 pForward->PushCell(hndl);
1.56 @@ -450,8 +449,8 @@
1.57 g_HandleSys.FreeHandle(hndl, &sec);
1.58
1.59 /* Free event structure */
1.60 - gameevents->FreeEvent(pEventCopy);
1.61 - pHook->pEventCopy = NULL;
1.62 + gameevents->FreeEvent(info.pEvent);
1.63 + m_EventCopies.pop();
1.64 }
1.65 }
1.66 }
2.1 --- a/core/EventManager.h Mon Jan 12 02:33:03 2009 -0500
2.2 +++ b/core/EventManager.h Tue Jan 27 23:53:48 2009 -0600
2.3 @@ -45,6 +45,12 @@
2.4
2.5 struct EventInfo
2.6 {
2.7 + EventInfo()
2.8 + {
2.9 + }
2.10 + EventInfo(IGameEvent *ev, IdentityToken_t *owner) : pEvent(ev), pOwner(owner)
2.11 + {
2.12 + }
2.13 IGameEvent *pEvent;
2.14 IdentityToken_t *pOwner;
2.15 };
2.16 @@ -56,13 +62,11 @@
2.17 pPreHook = NULL;
2.18 pPostHook = NULL;
2.19 postCopy = false;
2.20 - pEventCopy = NULL;
2.21 refCount = 0;
2.22 }
2.23 IChangeableForward *pPreHook;
2.24 IChangeableForward *pPostHook;
2.25 bool postCopy;
2.26 - IGameEvent *pEventCopy;
2.27 unsigned int refCount;
2.28 };
2.29
2.30 @@ -121,6 +125,7 @@
2.31 Trie *m_EventHooks;
2.32 CStack<EventInfo *> m_FreeEvents;
2.33 CStack<const char *> m_EventNames;
2.34 + CStack<IGameEvent *> m_EventCopies;
2.35 };
2.36
2.37 extern EventManager g_EventManager;