Fixed amb190 - Crash with Mani's spawn protection and GetEvent (which exposed re-entrancy problems in EventManager)
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40690
This commit is contained in:
parent
3b8864193d
commit
4e6834a7a4
@ -25,7 +25,7 @@ SH_DECL_HOOK2(IGameEventManager2, FireEvent, SH_NOATTRIB, 0, bool, IGameEvent *,
|
|||||||
const ParamType GAMEEVENT_PARAMS[] = {Param_Cell, Param_String, Param_Cell};
|
const ParamType GAMEEVENT_PARAMS[] = {Param_Cell, Param_String, Param_Cell};
|
||||||
typedef List<EventHook *> EventHookList;
|
typedef List<EventHook *> EventHookList;
|
||||||
|
|
||||||
EventManager::EventManager() : m_EventType(0), m_NotifyPlugins(true), m_EventCopy(NULL)
|
EventManager::EventManager() : m_EventType(0), m_NotifyPlugins(true)
|
||||||
{
|
{
|
||||||
/* Create an event lookup trie */
|
/* Create an event lookup trie */
|
||||||
m_EventHooks = sm_trie_create();
|
m_EventHooks = sm_trie_create();
|
||||||
@ -322,6 +322,7 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
{
|
{
|
||||||
EventHook *pHook;
|
EventHook *pHook;
|
||||||
IChangeableForward *pForward;
|
IChangeableForward *pForward;
|
||||||
|
const char *name;
|
||||||
cell_t res = Pl_Continue;
|
cell_t res = Pl_Continue;
|
||||||
|
|
||||||
if (!m_NotifyPlugins)
|
if (!m_NotifyPlugins)
|
||||||
@ -330,9 +331,11 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get the event name, we're going to need this for passing to post hooks */
|
/* Get the event name, we're going to need this for passing to post hooks */
|
||||||
m_EventName = pEvent->GetName();
|
name = pEvent->GetName();
|
||||||
|
|
||||||
if (sm_trie_retrieve(m_EventHooks, m_EventName, reinterpret_cast<void **>(&pHook)))
|
m_EventNames.push(name);
|
||||||
|
|
||||||
|
if (sm_trie_retrieve(m_EventHooks, name, reinterpret_cast<void **>(&pHook)))
|
||||||
{
|
{
|
||||||
pForward = pHook->pPreHook;
|
pForward = pHook->pPreHook;
|
||||||
|
|
||||||
@ -342,7 +345,7 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
|
|
||||||
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(m_EventName);
|
pForward->PushString(name);
|
||||||
pForward->PushCell(bDontBroadcast);
|
pForward->PushCell(bDontBroadcast);
|
||||||
pForward->Execute(&res, NULL);
|
pForward->Execute(&res, NULL);
|
||||||
|
|
||||||
@ -352,7 +355,7 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
|
|
||||||
if (pHook->postCopy)
|
if (pHook->postCopy)
|
||||||
{
|
{
|
||||||
m_EventCopy = gameevents->DuplicateEvent(pEvent);
|
pHook->pEventCopy = gameevents->DuplicateEvent(pEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
@ -368,8 +371,10 @@ 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;
|
||||||
EventHook *pHook;
|
EventHook *pHook;
|
||||||
IChangeableForward *pForward;
|
IChangeableForward *pForward;
|
||||||
|
const char *name;
|
||||||
Handle_t hndl = 0;
|
Handle_t hndl = 0;
|
||||||
|
|
||||||
if (!m_NotifyPlugins)
|
if (!m_NotifyPlugins)
|
||||||
@ -380,7 +385,9 @@ bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
RETURN_META_VALUE(MRES_IGNORED, true);
|
RETURN_META_VALUE(MRES_IGNORED, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sm_trie_retrieve(m_EventHooks, m_EventName, reinterpret_cast<void **>(&pHook)))
|
name = m_EventNames.front();
|
||||||
|
|
||||||
|
if (sm_trie_retrieve(m_EventHooks, name, reinterpret_cast<void **>(&pHook)))
|
||||||
{
|
{
|
||||||
pForward = pHook->pPostHook;
|
pForward = pHook->pPostHook;
|
||||||
|
|
||||||
@ -388,14 +395,17 @@ bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
{
|
{
|
||||||
if (pHook->postCopy)
|
if (pHook->postCopy)
|
||||||
{
|
{
|
||||||
EventInfo info = {m_EventCopy, false};
|
pEventCopy = pHook->pEventCopy;
|
||||||
|
|
||||||
|
EventInfo info = {pEventCopy, false};
|
||||||
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);
|
||||||
} else {
|
} else {
|
||||||
pForward->PushCell(BAD_HANDLE);
|
pForward->PushCell(BAD_HANDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
pForward->PushString(m_EventName);
|
pForward->PushString(name);
|
||||||
pForward->PushCell(bDontBroadcast);
|
pForward->PushCell(bDontBroadcast);
|
||||||
pForward->Execute(NULL);
|
pForward->Execute(NULL);
|
||||||
|
|
||||||
@ -406,11 +416,13 @@ 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(m_EventCopy);
|
gameevents->FreeEvent(pEventCopy);
|
||||||
m_EventCopy = NULL;
|
pHook->pEventCopy = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_EventNames.pop();
|
||||||
|
|
||||||
RETURN_META_VALUE(MRES_IGNORED, true);
|
RETURN_META_VALUE(MRES_IGNORED, true);
|
||||||
}
|
}
|
||||||
|
@ -42,11 +42,13 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -102,10 +104,9 @@ private: // IGameEventManager2 hooks
|
|||||||
private:
|
private:
|
||||||
HandleType_t m_EventType;
|
HandleType_t m_EventType;
|
||||||
bool m_NotifyPlugins;
|
bool m_NotifyPlugins;
|
||||||
const char *m_EventName;
|
|
||||||
IGameEvent *m_EventCopy;
|
|
||||||
Trie *m_EventHooks;
|
Trie *m_EventHooks;
|
||||||
CStack<EventInfo *> m_FreeEvents;
|
CStack<EventInfo *> m_FreeEvents;
|
||||||
|
CStack<const char *> m_EventNames;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern EventManager g_EventManager;
|
extern EventManager g_EventManager;
|
||||||
|
Loading…
Reference in New Issue
Block a user