Merge pull request #13506 from sabrina-shanman/fix-osx-crash-on-exit

Fix Mac Crashes On Shutdown
This commit is contained in:
John Conklin II 2018-07-02 15:27:26 -07:00 committed by GitHub
commit 3f975cfa84
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 57 additions and 29 deletions

View file

@ -64,6 +64,7 @@ Agent::Agent(ReceivedMessage& message) :
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
DependencyManager::set<ResourceManager>();
DependencyManager::set<PluginManager>();
DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>();
@ -833,6 +834,8 @@ void Agent::aboutToFinish() {
DependencyManager::get<ResourceManager>()->cleanup();
DependencyManager::destroy<PluginManager>();
// cleanup the AudioInjectorManager (and any still running injectors)
DependencyManager::destroy<AudioInjectorManager>();

View file

@ -65,7 +65,8 @@ AudioMixer::AudioMixer(ReceivedMessage& message) :
// hash the available codecs (on the mixer)
_availableCodecs.clear(); // Make sure struct is clean
auto codecPlugins = PluginManager::getInstance()->getCodecPlugins();
auto pluginManager = DependencyManager::set<PluginManager>();
auto codecPlugins = pluginManager->getCodecPlugins();
std::for_each(codecPlugins.cbegin(), codecPlugins.cend(),
[&](const CodecPluginPointer& codec) {
_availableCodecs[codec->getName()] = codec;
@ -106,6 +107,10 @@ AudioMixer::AudioMixer(ReceivedMessage& message) :
connect(nodeList.data(), &NodeList::nodeKilled, this, &AudioMixer::handleNodeKilled);
}
void AudioMixer::aboutToFinish() {
DependencyManager::destroy<PluginManager>();
}
void AudioMixer::queueAudioPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer node) {
if (message->getType() == PacketType::SilentAudioFrame) {
_numSilentPackets++;

View file

@ -58,6 +58,9 @@ public:
to.getPublicSocket() != from.getPublicSocket() &&
to.getLocalSocket() != from.getLocalSocket();
}
virtual void aboutToFinish() override;
public slots:
void run() override;
void sendStatsPacket() override;

View file

@ -58,6 +58,7 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
DependencyManager::set<ResourceManager>();
DependencyManager::set<PluginManager>();
DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>();
@ -572,6 +573,8 @@ void EntityScriptServer::aboutToFinish() {
DependencyManager::get<ResourceManager>()->cleanup();
DependencyManager::destroy<PluginManager>();
// cleanup the AudioInjectorManager (and any still running injectors)
DependencyManager::destroy<AudioInjectorManager>();
DependencyManager::destroy<ScriptEngines>();

View file

@ -269,9 +269,6 @@ public:
}
_renderContext->doneCurrent();
// Deleting the object with automatically shutdown the thread
connect(qApp, &QCoreApplication::aboutToQuit, this, &QObject::deleteLater);
// Transfer to a new thread
moveToNewNamedThread(this, "RenderThread", [this](QThread* renderThread) {
hifi::qt::addBlockingForbiddenThread("Render", renderThread);
@ -814,6 +811,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
}
// Tell the plugin manager about our statically linked plugins
DependencyManager::set<PluginManager>();
auto pluginManager = PluginManager::getInstance();
pluginManager->setInputPluginProvider([] { return getInputPlugins(); });
pluginManager->setDisplayPluginProvider([] { return getDisplayPlugins(); });
@ -1378,6 +1376,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
initializeRenderEngine();
qCDebug(interfaceapp, "Initialized Render Engine.");
// Overlays need to exist before we set the ContextOverlayInterface dependency
_overlays.init(); // do this before scripts load
DependencyManager::set<ContextOverlayInterface>();
// Initialize the user interface and menu system
// Needs to happen AFTER the render engine initialization to access its configuration
initializeUi();
@ -1514,10 +1516,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
// allow you to move an entity around in your hand
_entityEditSender.setPacketsPerSecond(3000); // super high!!
// Overlays need to exist before we set the ContextOverlayInterface dependency
_overlays.init(); // do this before scripts load
DependencyManager::set<ContextOverlayInterface>();
// Make sure we don't time out during slow operations at startup
updateHeartbeat();
@ -2555,25 +2553,28 @@ Application::~Application() {
_octreeProcessor.terminate();
_entityEditSender.terminate();
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
steamClient->shutdown();
}
DependencyManager::destroy<PluginManager>();
DependencyManager::destroy<CompositorHelper>(); // must be destroyed before the FramebufferCache
DependencyManager::destroy<AvatarManager>();
DependencyManager::destroy<AnimationCache>();
DependencyManager::destroy<FramebufferCache>();
DependencyManager::destroy<TextureCache>();
DependencyManager::destroy<ModelCache>();
DependencyManager::destroy<GeometryCache>();
DependencyManager::destroy<ScriptCache>();
DependencyManager::destroy<SoundCache>();
DependencyManager::destroy<OctreeStatsProvider>();
DependencyManager::destroy<GeometryCache>();
DependencyManager::get<ResourceManager>()->cleanup();
// remove the NodeList from the DependencyManager
DependencyManager::destroy<NodeList>();
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
steamClient->shutdown();
}
#if 0
ConnexionClient::getInstance().destroy();
#endif
@ -2593,6 +2594,8 @@ Application::~Application() {
// Can't log to file passed this point, FileLogger about to be deleted
qInstallMessageHandler(LogHandler::verboseMessageHandler);
_renderEventHandler->deleteLater();
}
void Application::initializeGL() {
@ -2893,6 +2896,7 @@ void Application::initializeUi() {
auto compositorHelper = DependencyManager::get<CompositorHelper>();
connect(compositorHelper.data(), &CompositorHelper::allowMouseCaptureChanged, this, [=] {
if (isHMDMode()) {
auto compositorHelper = DependencyManager::get<CompositorHelper>(); // don't capture outer smartpointer
showCursor(compositorHelper->getAllowMouseCapture() ?
Cursor::Manager::lookupIcon(_preferredCursor.get()) :
Cursor::Icon::SYSTEM);

View file

@ -139,7 +139,10 @@ void Application::paintGL() {
frame->frameIndex = _renderFrameCount;
frame->framebuffer = finalFramebuffer;
frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) {
DependencyManager::get<FramebufferCache>()->releaseFramebuffer(framebuffer);
auto frameBufferCache = DependencyManager::get<FramebufferCache>();
if (frameBufferCache) {
frameBufferCache->releaseFramebuffer(framebuffer);
}
};
// deliver final scene rendering commands to the display plugin
{

View file

@ -21,10 +21,7 @@ Frame::~Frame() {
framebuffer.reset();
}
assert(bufferUpdates.empty());
if (!bufferUpdates.empty()) {
qFatal("Buffer sync error... frame destroyed without buffer updates being applied");
}
bufferUpdates.clear();
}
void Frame::finish() {

View file

@ -39,8 +39,13 @@ ResourceManager::ResourceManager(bool atpSupportEnabled) : _atpSupportEnabled(at
}
ResourceManager::~ResourceManager() {
_thread.terminate();
_thread.wait();
if (_thread.isRunning()) {
_thread.quit();
static const auto MAX_RESOURCE_MANAGER_THREAD_QUITTING_TIME = MSECS_PER_SECOND / 2;
if (!_thread.wait(MAX_RESOURCE_MANAGER_THREAD_QUITTING_TIME)) {
_thread.terminate();
}
}
}
void ResourceManager::setUrlPrefixOverride(const QString& prefix, const QString& replacement) {

View file

@ -40,9 +40,8 @@ void PluginManager::setInputPluginSettingsPersister(const InputPluginSettingsPer
_inputSettingsPersister = persister;
}
PluginManager* PluginManager::getInstance() {
static PluginManager _manager;
return &_manager;
PluginManagerPointer PluginManager::getInstance() {
return DependencyManager::get<PluginManager>();
}
QString getPluginNameFromMetaData(QJsonObject object) {
@ -136,9 +135,6 @@ const LoaderList& getLoadedPlugins() {
return loadedPlugins;
}
PluginManager::PluginManager() {
}
const CodecPluginList& PluginManager::getCodecPlugins() {
static CodecPluginList codecPlugins;
static std::once_flag once;

View file

@ -9,12 +9,19 @@
#include <QObject>
#include <DependencyManager.h>
#include "Forward.h"
class PluginManager : public QObject {
class PluginManager;
using PluginManagerPointer = QSharedPointer<PluginManager>;
class PluginManager : public QObject, public Dependency {
SINGLETON_DEPENDENCY
public:
static PluginManager* getInstance();
PluginManager();
static PluginManagerPointer getInstance();
const DisplayPluginList& getDisplayPlugins();
const InputPluginList& getInputPlugins();
@ -39,6 +46,8 @@ public:
void setInputPluginSettingsPersister(const InputPluginSettingsPersister& persister);
private:
PluginManager() = default;
DisplayPluginProvider _displayPluginProvider { []()->DisplayPluginList { return {}; } };
InputPluginProvider _inputPluginProvider { []()->InputPluginList { return {}; } };
CodecPluginProvider _codecPluginProvider { []()->CodecPluginList { return {}; } };