From c0c0fa606baa117d32b315d126ea3f65f963d749 Mon Sep 17 00:00:00 2001 From: Sour Date: Sat, 16 Jun 2018 10:03:49 -0400 Subject: [PATCH] Fixed potential multithread crashes that could occur under certain circumstances (e.g when a game crashes) --- Core/Console.cpp | 90 ++++++++++++++++++++++++++++++------------------ Core/Console.h | 2 +- Mesen.sln | 5 --- 3 files changed, 58 insertions(+), 39 deletions(-) diff --git a/Core/Console.cpp b/Core/Console.cpp index b15d85c5..15d4ff38 100644 --- a/Core/Console.cpp +++ b/Core/Console.cpp @@ -65,12 +65,15 @@ void Console::Release() void Console::SaveBatteries() { - if(_mapper) { - _mapper->SaveBattery(); + shared_ptr mapper = _mapper; + shared_ptr controlManager = _controlManager; + + if(mapper) { + mapper->SaveBattery(); } - if(_controlManager) { - shared_ptr device = std::dynamic_pointer_cast(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort)); + if(controlManager) { + shared_ptr device = std::dynamic_pointer_cast(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort)); if(device) { device->SaveBattery(); } @@ -868,18 +871,20 @@ bool Console::UpdateHdPackMode() ConsoleFeatures Console::GetAvailableFeatures() { ConsoleFeatures features = ConsoleFeatures::None; - if(_mapper) { - features = (ConsoleFeatures)((int)features | (int)_mapper->GetAvailableFeatures()); + shared_ptr mapper = _mapper; + shared_ptr controlManager = controlManager; + if(mapper && controlManager) { + features = (ConsoleFeatures)((int)features | (int)mapper->GetAvailableFeatures()); - if(dynamic_cast(_controlManager.get())) { + if(dynamic_cast(controlManager.get())) { features = (ConsoleFeatures)((int)features | (int)ConsoleFeatures::VsSystem); } - if(std::dynamic_pointer_cast(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort))) { + if(std::dynamic_pointer_cast(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort))) { features = (ConsoleFeatures)((int)features | (int)ConsoleFeatures::BarcodeReader); } - if(std::dynamic_pointer_cast(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2))) { + if(std::dynamic_pointer_cast(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2))) { features = (ConsoleFeatures)((int)features | (int)ConsoleFeatures::TapeRecorder); } } @@ -888,52 +893,71 @@ ConsoleFeatures Console::GetAvailableFeatures() void Console::InputBarcode(uint64_t barcode, uint32_t digitCount) { - shared_ptr barcodeReader = std::dynamic_pointer_cast(_mapper->GetMapperControlDevice()); - if(barcodeReader) { - barcodeReader->InputBarcode(barcode, digitCount); + shared_ptr mapper = _mapper; + shared_ptr controlManager = controlManager; + + if(mapper) { + shared_ptr barcodeReader = std::dynamic_pointer_cast(mapper->GetMapperControlDevice()); + if(barcodeReader) { + barcodeReader->InputBarcode(barcode, digitCount); + } } - barcodeReader = std::dynamic_pointer_cast(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort)); - if(barcodeReader) { - barcodeReader->InputBarcode(barcode, digitCount); + if(controlManager) { + shared_ptr barcodeReader = std::dynamic_pointer_cast(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort)); + if(barcodeReader) { + barcodeReader->InputBarcode(barcode, digitCount); + } } } void Console::LoadTapeFile(string filepath) { - shared_ptr dataRecorder = std::dynamic_pointer_cast(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2)); - if(dataRecorder) { - Console::Pause(); - dataRecorder->LoadFromFile(filepath); - Console::Resume(); + shared_ptr controlManager = _controlManager; + if(controlManager) { + shared_ptr dataRecorder = std::dynamic_pointer_cast(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2)); + if(dataRecorder) { + Console::Pause(); + dataRecorder->LoadFromFile(filepath); + Console::Resume(); + } } } void Console::StartRecordingTapeFile(string filepath) { - shared_ptr dataRecorder = std::dynamic_pointer_cast(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2)); - if(dataRecorder) { - Console::Pause(); - dataRecorder->StartRecording(filepath); - Console::Resume(); + shared_ptr controlManager = _controlManager; + if(controlManager) { + shared_ptr dataRecorder = std::dynamic_pointer_cast(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2)); + if(dataRecorder) { + Console::Pause(); + dataRecorder->StartRecording(filepath); + Console::Resume(); + } } } void Console::StopRecordingTapeFile() { - shared_ptr dataRecorder = std::dynamic_pointer_cast(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2)); - if(dataRecorder) { - Console::Pause(); - dataRecorder->StopRecording(); - Console::Resume(); + shared_ptr controlManager = _controlManager; + if(controlManager) { + shared_ptr dataRecorder = std::dynamic_pointer_cast(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2)); + if(dataRecorder) { + Console::Pause(); + dataRecorder->StopRecording(); + Console::Resume(); + } } } bool Console::IsRecordingTapeFile() { - shared_ptr dataRecorder = std::dynamic_pointer_cast(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2)); - if(dataRecorder) { - return dataRecorder->IsRecording(); + shared_ptr controlManager = _controlManager; + if(controlManager) { + shared_ptr dataRecorder = std::dynamic_pointer_cast(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2)); + if(dataRecorder) { + return dataRecorder->IsRecording(); + } } return false; diff --git a/Core/Console.h b/Core/Console.h index eb3aa9c5..b4a9e364 100644 --- a/Core/Console.h +++ b/Core/Console.h @@ -41,7 +41,7 @@ class Console shared_ptr _apu; shared_ptr _debugger; shared_ptr _mapper; - unique_ptr _controlManager; + shared_ptr _controlManager; shared_ptr _memoryManager; shared_ptr _systemActionManager; diff --git a/Mesen.sln b/Mesen.sln index 313ae601..f2285c73 100644 --- a/Mesen.sln +++ b/Mesen.sln @@ -62,11 +62,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Libretro", "Libretro\Libret {78FEF1A1-6DF1-4CBB-A373-AE6FA7CE5CE0} = {78FEF1A1-6DF1-4CBB-A373-AE6FA7CE5CE0} EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{54D3FF68-C2AE-4D22-BFED-D84191E1D23C}" - ProjectSection(SolutionItems) = preProject - Performance1.psess = Performance1.psess - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU