From 49e4283807c7cfec4933b3c3e7b858f481280bd8 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Tue, 30 Jun 2020 10:06:51 -0600 Subject: [PATCH] Fix the "Crash on Exit" bug (cherry picked from commit b4f6ccaa8873b5560d618fb9cfee79691ef5990a) We were throwing away the Dispatcher before all the keys (namely, leaked keys) were unloaded. See the comment in plResManager for more details. --- .../Sources/Plasma/NucleusLib/inc/plgDispatch.h | 2 ++ .../Plasma/NucleusLib/pnDispatch/plDispatch.cpp | 10 ++++++---- .../Plasma/NucleusLib/pnDispatch/plDispatch.h | 4 +++- .../Plasma/PubUtilLib/plResMgr/plResManager.cpp | 15 ++++++++++----- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/NucleusLib/inc/plgDispatch.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/NucleusLib/inc/plgDispatch.h index a7829a62..98add244 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/NucleusLib/inc/plgDispatch.h +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/NucleusLib/inc/plgDispatch.h @@ -68,6 +68,8 @@ public: virtual void MsgQueueOnOff(hsBool) = 0; // Turn on or off Queued Messages, if off, uses MsgSend Immediately (for plugins) virtual hsBool SetMsgBuffering(hsBool on) = 0; // On starts deferring msg delivery until buffering is set to off again. + + virtual bool BeginShutdown() = 0; }; class plgDispatch diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/NucleusLib/pnDispatch/plDispatch.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/NucleusLib/pnDispatch/plDispatch.cpp index 6bc3db35..7b1f1bf8 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/NucleusLib/pnDispatch/plDispatch.cpp +++ b/MOULOpenSourceClientPlugin/Plasma20/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/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/NucleusLib/pnDispatch/plDispatch.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/NucleusLib/pnDispatch/plDispatch.h index a001891b..89ab0bcc 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/NucleusLib/pnDispatch/plDispatch.h +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/NucleusLib/pnDispatch/plDispatch.h @@ -131,6 +131,8 @@ public: virtual hsBool SetMsgBuffering(hsBool on); // On starts deferring msg delivery until buffering is set to off again. + virtual void BeginShutdown(); + static void SetMsgRecieveCallback(MsgRecieveCallback callback) { fMsgRecieveCallback = callback; } }; @@ -145,7 +147,7 @@ public: virtual void UnRegisterForType(UInt16 hClass, const plKey& receiver) {} - virtual hsBool MsgSend(plMessage* msg) {} + virtual hsBool MsgSend(plMessage* msg) {} virtual void MsgQueue(plMessage* msg){} virtual void MsgQueueProcess(){} diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp index 423d732f..50e66c39 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp @@ -205,10 +205,12 @@ 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 +226,12 @@ void plResManager::IShutdown() fLoadedPages.clear(); IUnlockPages(); - fLastFoundPage = nil; + // Now, kill off the Dispatcher + hsRefCnt_SafeUnRef(fDispatch); + fDispatch = nil; + kResMgrLog(1, ILog(1, " ...Shutdown successful!")); fInited = false;