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).
authorScott Ehlert <ds@alliedmods.net>
Tue Jan 27 23:53:48 2009 -0600 (2009-01-27)
changeset 2538f3392408c5ad
parent 2537 045221a32f50
child 2539 6a02043f203b
child 2549 8d2974380f78
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.
core/EventManager.cpp
core/EventManager.h
     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;