diff --git a/Sources/Plasma/NucleusLib/inc/plgDispatch.h b/Sources/Plasma/NucleusLib/inc/plgDispatch.h index c62a2061..344cf1a4 100644 --- a/Sources/Plasma/NucleusLib/inc/plgDispatch.h +++ b/Sources/Plasma/NucleusLib/inc/plgDispatch.h @@ -68,6 +68,8 @@ public: virtual void MsgQueueOnOff(bool) = 0; // Turn on or off Queued Messages, if off, uses MsgSend Immediately (for plugins) virtual bool SetMsgBuffering(bool on) = 0; // On starts deferring msg delivery until buffering is set to off again. + + virtual void BeginShutdown() = 0; }; class plgDispatch diff --git a/Sources/Plasma/NucleusLib/pnDispatch/plDispatch.cpp b/Sources/Plasma/NucleusLib/pnDispatch/plDispatch.cpp index 38297684..16b15897 100644 --- a/Sources/Plasma/NucleusLib/pnDispatch/plDispatch.cpp +++ b/Sources/Plasma/NucleusLib/pnDispatch/plDispatch.cpp @@ -103,12 +103,14 @@ plDispatch::plDispatch() plDispatch::~plDispatch() { - int i; - for( i = 0; i < fRegisteredExactTypes.GetCount(); i++ ) - delete fRegisteredExactTypes[i]; - + hsAssert(fRegisteredExactTypes.GetCount() == 0, "registered type after Dispatch shutdown"); ITrashUndelivered(); +} +void plDispatch::BeginShutdown() +{ + fRegisteredExactTypes.Reset(); + ITrashUndelivered(); } void plDispatch::ITrashUndelivered() diff --git a/Sources/Plasma/NucleusLib/pnDispatch/plDispatch.h b/Sources/Plasma/NucleusLib/pnDispatch/plDispatch.h index 9554673c..a4b31329 100644 --- a/Sources/Plasma/NucleusLib/pnDispatch/plDispatch.h +++ b/Sources/Plasma/NucleusLib/pnDispatch/plDispatch.h @@ -131,6 +131,8 @@ public: virtual bool SetMsgBuffering(bool on); // On starts deferring msg delivery until buffering is set to off again. + virtual void BeginShutdown(); + static void SetMsgRecieveCallback(MsgRecieveCallback callback) { fMsgRecieveCallback = callback; } }; @@ -146,8 +148,10 @@ public: virtual bool MsgSend(plMessage* msg) { return true; } - virtual void MsgQueue(plMessage* msg) {} - virtual void MsgQueueProcess() {} + virtual void MsgQueue(plMessage* msg) {} + virtual void MsgQueueProcess() {} + + virtual void BeginShutdown() {} }; diff --git a/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp b/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp index eda1d7ae..dd159cc2 100644 --- a/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp +++ b/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp @@ -205,10 +205,11 @@ void plResManager::IShutdown() // TimerCallbackMgr is a fixed-keyed object, so needs to shut down before the registry plgTimerCallbackMgr::Shutdown(); - // Destroy the dispatch. Note that we do this before the registry so that any lingering messages - // can free up keys properly - hsRefCnt_SafeUnRef(fDispatch); - fDispatch = nil; + // Formerly, we destroyed the Dispatcher here to clean up keys for leak reporting. + // However, if there are *real* leaked keys, then they will want to unload after this step. + // To unload, plKeyImp needs to dispatcher. SO, we're going to pitch everything currently in the + // Dispatcher and kill it later + fDispatch->BeginShutdown(); // Just before we shut down the registry, page out any keys that still exist. // (They shouldn't... they're baaaaaad.) @@ -224,9 +225,12 @@ void plResManager::IShutdown() fLoadedPages.clear(); IUnlockPages(); - fLastFoundPage = nil; + // Now, kill off the Dispatcher + hsRefCnt_SafeUnRef(fDispatch); + fDispatch = nullptr; + kResMgrLog(1, ILog(1, " ...Shutdown successful!")); fInited = false;