diff --git a/Core/ELF/ElfReader.cpp b/Core/ELF/ElfReader.cpp index ee4c2e2bf..745766df9 100644 --- a/Core/ELF/ElfReader.cpp +++ b/Core/ELF/ElfReader.cpp @@ -677,7 +677,3 @@ bool ElfReader::LoadSymbols() } return hasSymbols; } - - - - diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 4c9395cfe..d125ec225 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1703,29 +1703,29 @@ void __KernelReSchedule(const char *reason) // Execute any pending events while we're doing scheduling. CoreTiming::Advance(); - if (__IsInInterrupt() || !__KernelIsDispatchEnabled()) - { + if (__IsInInterrupt() || !__KernelIsDispatchEnabled()) { // Threads don't get changed within interrupts or while dispatch is disabled. reason = "In Interrupt Or Callback"; return; } Thread *nextThread = __KernelNextThread(); - if (nextThread) + if (nextThread) { __KernelSwitchContext(nextThread, reason); + } // Otherwise, no need to switch. } void __KernelReSchedule(bool doCallbacks, const char *reason) { Thread *thread = __GetCurrentThread(); - if (doCallbacks) - { - if (thread) - thread->isProcessingCallbacks = doCallbacks; + if (doCallbacks && thread != nullptr) { + thread->isProcessingCallbacks = doCallbacks; } + + // Note - this calls the function above, not this one. Overloading... __KernelReSchedule(reason); - if (doCallbacks && thread != NULL && thread->GetUID() == currentThread) { + if (doCallbacks && thread != nullptr && thread->GetUID() == currentThread) { if (thread->isRunning()) { thread->isProcessingCallbacks = false; } diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index a43315e3d..cf6ce9448 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -155,15 +155,18 @@ namespace Reporting if (output == NULL) output = &theVoid; - if (http.Resolve(ServerHostname(), ServerPort())) - { + const char *serverHost = ServerHostname(); + if (!serverHost) + return false; + + if (http.Resolve(serverHost, ServerPort())) { http.Connect(); http.POST(uri, data, mimeType, output); http.Disconnect(); - result = true; + return true; + } else { + return false; } - - return result; } std::string StripTrailingNull(const std::string &str) diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index c0128d9b8..89552ec9f 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -206,6 +206,9 @@ int PlayBackgroundAudio() { // last changed... (to prevent crazy amount of reads when skipping through a list) if (!at3Reader && bgGamePath.size() && (time_now_d() - gameLastChanged > 0.5)) { // Grab some audio from the current game and play it. + if (!g_gameInfoCache) + return 0; // race condition? + GameInfo *gameInfo = g_gameInfoCache->GetInfo(NULL, bgGamePath, GAMEINFO_WANTSND); if (!gameInfo) return 0; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 90d5044df..786e4e512 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -611,7 +611,9 @@ void NativeShutdownGraphics() { delete g_gameInfoCache; g_gameInfoCache = nullptr; - uiTexture->Release(); + if (uiTexture->Release()) { + uiTexture = nullptr; + } delete uiContext; uiContext = NULL; @@ -619,7 +621,10 @@ void NativeShutdownGraphics() { ui_draw2d.Shutdown(); ui_draw2d_front.Shutdown(); - thin3d->Release(); + // TODO: Reconsider this annoying ref counting stuff. + if (thin3d->Release()) { + thin3d = nullptr; + } } void TakeScreenshot() { diff --git a/android/jni/native-audio-so.cpp b/android/jni/native-audio-so.cpp index 901fdeea2..4178e442c 100644 --- a/android/jni/native-audio-so.cpp +++ b/android/jni/native-audio-so.cpp @@ -73,19 +73,22 @@ bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleR framesPerBuffer = 256; if (framesPerBuffer < 32) framesPerBuffer = 32; + if (framesPerBuffer > 4096) + framesPerBuffer = 4096; + sampleRate = _SampleRate; if (sampleRate != 44100 && sampleRate != 48000) { ELOG("Invalid sample rate %i - choosing 44100", sampleRate); sampleRate = 44100; } - buffer[0] = new short[framesPerBuffer * 2]; - buffer[1] = new short[framesPerBuffer * 2]; - SLresult result; // create engine result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); - assert(SL_RESULT_SUCCESS == result); + if (result != SL_RESULT_SUCCESS) { + ELOG("OpenSL ES: Failed to create the engine: %d", (int)result); + return false; + } result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); assert(SL_RESULT_SUCCESS == result); result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); @@ -98,7 +101,7 @@ bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleR SLuint32 sr = SL_SAMPLINGRATE_44_1; if (sampleRate == 48000) { sr = SL_SAMPLINGRATE_48; - } + } // Don't allow any other sample rates. SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; SLDataFormat_PCM format_pcm = { @@ -121,7 +124,11 @@ bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleR const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME}; const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req); - assert(SL_RESULT_SUCCESS == result); + if (result != SL_RESULT_SUCCESS) { + ELOG("OpenSL ES: CreateAudioPlayer failed: %d", (int)result); + // Should really tear everything down here. Sigh. + return false; + } result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE); assert(SL_RESULT_SUCCESS == result); @@ -138,6 +145,9 @@ bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleR assert(SL_RESULT_SUCCESS == result); // Render and enqueue a first buffer. (or should we just play the buffer empty?) + buffer[0] = new short[framesPerBuffer * 2]; + buffer[1] = new short[framesPerBuffer * 2]; + curBuffer = 0; audioCallback(buffer[curBuffer], framesPerBuffer); @@ -151,40 +161,44 @@ bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleR // shut down the native audio system void OpenSLWrap_Shutdown() { - SLresult result; - ILOG("OpenSLWrap_Shutdown - stopping playback"); - result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED); - if (SL_RESULT_SUCCESS != result) { - ELOG("SetPlayState failed"); + if (bqPlayerPlay) { + ILOG("OpenSLWrap_Shutdown - stopping playback"); + SLresult result; + result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED); + if (SL_RESULT_SUCCESS != result) { + ELOG("SetPlayState failed"); + } } ILOG("OpenSLWrap_Shutdown - deleting player object"); - if (bqPlayerObject != NULL) { + if (bqPlayerObject) { (*bqPlayerObject)->Destroy(bqPlayerObject); - bqPlayerObject = NULL; - bqPlayerPlay = NULL; - bqPlayerBufferQueue = NULL; - bqPlayerMuteSolo = NULL; - bqPlayerVolume = NULL; + bqPlayerObject = nullptr; + bqPlayerPlay = nullptr; + bqPlayerBufferQueue = nullptr; + bqPlayerMuteSolo = nullptr; + bqPlayerVolume = nullptr; } ILOG("OpenSLWrap_Shutdown - deleting mix object"); - if (outputMixObject != NULL) { + if (outputMixObject) { (*outputMixObject)->Destroy(outputMixObject); - outputMixObject = NULL; + outputMixObject = nullptr; } ILOG("OpenSLWrap_Shutdown - deleting engine object"); - if (engineObject != NULL) { + if (engineObject) { (*engineObject)->Destroy(engineObject); - engineObject = NULL; - engineEngine = NULL; + engineObject = nullptr; + engineEngine = nullptr; } delete [] buffer[0]; delete [] buffer[1]; + buffer[0] = nullptr; + buffer[1] = nullptr; ILOG("OpenSLWrap_Shutdown - finished"); } diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 131ad0a60..447d82521 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -11,6 +11,8 @@ #include #include +#include "base/logging.h" + class Matrix4x4; enum T3DBlendEquation : int { @@ -212,8 +214,20 @@ public: Thin3DObject() : refcount_(1) {} virtual ~Thin3DObject() {} + // TODO: Reconsider this annoying ref counting stuff. virtual void AddRef() { refcount_++; } - virtual void Release() { refcount_--; if (!refcount_) delete this; } + virtual bool Release() { + if (refcount_ > 0 && refcount_ < 10000) { + refcount_--; + if (refcount_ == 0) { + delete this; + return true; + } + } else { + ELOG("Refcount (%d) invalid for object %p - corrupt?", refcount_, this); + } + return false; + } private: int refcount_; diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index acad8fbac..ad02a88f0 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -58,6 +58,9 @@ void UIScreen::update(InputState &input) { void UIScreen::preRender() { Thin3DContext *thin3d = screenManager()->getThin3DContext(); + if (!thin3d) { + return; + } thin3d->Begin(true, 0xFF000000, 0.0f, 0); T3DViewport viewport; @@ -73,6 +76,9 @@ void UIScreen::preRender() { void UIScreen::postRender() { Thin3DContext *thin3d = screenManager()->getThin3DContext(); + if (!thin3d) { + return; + } thin3d->End(); }