Skip to content

Commit

Permalink
#5200: Free the map right before the modules are shut down.
Browse files Browse the repository at this point in the history
Fix a crash in the MediaBrowser due to the ShaderClipboard firing callbacks after the tree view has been destroyed.
  • Loading branch information
codereader committed Aug 28, 2020
1 parent 89cf6c5 commit b78b392
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 10 deletions.
8 changes: 8 additions & 0 deletions include/imodule.h
Expand Up @@ -301,8 +301,16 @@ class IModuleRegistry
typedef sigc::signal<void, const std::string&, float> ProgressSignal;
virtual ProgressSignal& signal_moduleInitialisationProgress() = 0;

/**
* Invoked right before all modules are going to uninitialised, at the
* beginning of the radiant shutdown phase.
* This is a fire-once signal which removes all subscribers after firing.
*/
virtual sigc::signal<void>& signal_modulesUninitialising() = 0;

/**
* Invoked when all modules have been shut down (i.e. after shutdownModule()).
* This is a fire-once signal which removes all subscribers after firing.
*/
virtual sigc::signal<void>& signal_allModulesUninitialised() = 0;

Expand Down
3 changes: 3 additions & 0 deletions radiant/ui/mediabrowser/MediaBrowser.cpp
Expand Up @@ -533,6 +533,9 @@ void MediaBrowser::construct()
if (ev.GetEventObject() == _mainWidget)
{
_treeView = nullptr;
_shaderClipboardConn.disconnect();
_materialDefsLoaded.disconnect();
_materialDefsUnloaded.disconnect();
}
ev.Skip();
});
Expand Down
11 changes: 3 additions & 8 deletions radiantcore/map/Map.cpp
Expand Up @@ -845,7 +845,6 @@ const StringSet& Map::getDependencies() const

if (_dependencies.empty())
{
_dependencies.insert(MODULE_RADIANT_APP);
_dependencies.insert(MODULE_GAMEMANAGER);
_dependencies.insert(MODULE_SCENEGRAPH);
_dependencies.insert(MODULE_MAPINFOFILEMANAGER);
Expand Down Expand Up @@ -878,8 +877,9 @@ void Map::initialiseModule(const IApplicationContext& ctx)
std::make_shared<MapPropertyInfoFileModule>()
);

GlobalRadiant().signal_radiantShutdown().connect(
sigc::mem_fun(this, &Map::onRadiantShutdown)
// Free the map right before all modules are shut down
module::GlobalModuleRegistry().signal_modulesUninitialising().connect(
sigc::mem_fun(this, &Map::freeMap)
);

_shutdownListener = GlobalRadiantCore().getMessageBus().addListener(
Expand Down Expand Up @@ -908,9 +908,4 @@ void Map::handleShutdownRequest(radiant::ApplicationShutdownRequest& request)
}
}

void Map::onRadiantShutdown()
{
freeMap();
}

} // namespace map
2 changes: 0 additions & 2 deletions radiantcore/map/Map.h
Expand Up @@ -229,8 +229,6 @@ class Map :

void clearMapResource();

void onRadiantShutdown();

}; // class Map

} // namespace map
Expand Down
8 changes: 8 additions & 0 deletions radiantcore/modulesystem/ModuleRegistry.cpp
Expand Up @@ -196,6 +196,9 @@ void ModuleRegistry::shutdownModules()
throw std::logic_error("ModuleRegistry: shutdownModules called twice.");
}

_sigModulesUninitialising.emit();
_sigModulesUninitialising.clear();

for (ModulesMap::value_type& pair : _initialisedModules)
{
pair.second->shutdownModule();
Expand Down Expand Up @@ -270,6 +273,11 @@ ModuleRegistry::ProgressSignal& ModuleRegistry::signal_moduleInitialisationProgr
return _sigModuleInitialisationProgress;
}

sigc::signal<void>& ModuleRegistry::signal_modulesUninitialising()
{
return _sigModulesUninitialising;
}

sigc::signal<void>& ModuleRegistry::signal_allModulesUninitialised()
{
return _sigAllModulesUninitialised;
Expand Down
2 changes: 2 additions & 0 deletions radiantcore/modulesystem/ModuleRegistry.h
Expand Up @@ -44,6 +44,7 @@ class ModuleRegistry :
sigc::signal<void> _sigAllModulesInitialised;
sigc::signal<void> _sigAllModulesUninitialised;
sigc::signal<void> _sigModulesUnloading;
sigc::signal<void> _sigModulesUninitialising;
ProgressSignal _sigModuleInitialisationProgress;

// Dynamic library loader
Expand Down Expand Up @@ -76,6 +77,7 @@ class ModuleRegistry :

sigc::signal<void>& signal_allModulesInitialised() override;
ProgressSignal& signal_moduleInitialisationProgress() override;
sigc::signal<void>& signal_modulesUninitialising() override;
sigc::signal<void>& signal_allModulesUninitialised() override;
sigc::signal<void>& signal_modulesUnloading() override;

Expand Down

0 comments on commit b78b392

Please sign in to comment.