Fixed potential multithread crashes that could occur under certain circumstances (e.g when a game crashes)

This commit is contained in:
Sour 2018-06-16 10:03:49 -04:00
parent 71f3105f9d
commit c0c0fa606b
3 changed files with 58 additions and 39 deletions

View file

@ -65,12 +65,15 @@ void Console::Release()
void Console::SaveBatteries() void Console::SaveBatteries()
{ {
if(_mapper) { shared_ptr<BaseMapper> mapper = _mapper;
_mapper->SaveBattery(); shared_ptr<ControlManager> controlManager = _controlManager;
if(mapper) {
mapper->SaveBattery();
} }
if(_controlManager) { if(controlManager) {
shared_ptr<IBattery> device = std::dynamic_pointer_cast<IBattery>(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort)); shared_ptr<IBattery> device = std::dynamic_pointer_cast<IBattery>(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort));
if(device) { if(device) {
device->SaveBattery(); device->SaveBattery();
} }
@ -868,18 +871,20 @@ bool Console::UpdateHdPackMode()
ConsoleFeatures Console::GetAvailableFeatures() ConsoleFeatures Console::GetAvailableFeatures()
{ {
ConsoleFeatures features = ConsoleFeatures::None; ConsoleFeatures features = ConsoleFeatures::None;
if(_mapper) { shared_ptr<BaseMapper> mapper = _mapper;
features = (ConsoleFeatures)((int)features | (int)_mapper->GetAvailableFeatures()); shared_ptr<ControlManager> controlManager = controlManager;
if(mapper && controlManager) {
features = (ConsoleFeatures)((int)features | (int)mapper->GetAvailableFeatures());
if(dynamic_cast<VsControlManager*>(_controlManager.get())) { if(dynamic_cast<VsControlManager*>(controlManager.get())) {
features = (ConsoleFeatures)((int)features | (int)ConsoleFeatures::VsSystem); features = (ConsoleFeatures)((int)features | (int)ConsoleFeatures::VsSystem);
} }
if(std::dynamic_pointer_cast<IBarcodeReader>(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort))) { if(std::dynamic_pointer_cast<IBarcodeReader>(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort))) {
features = (ConsoleFeatures)((int)features | (int)ConsoleFeatures::BarcodeReader); features = (ConsoleFeatures)((int)features | (int)ConsoleFeatures::BarcodeReader);
} }
if(std::dynamic_pointer_cast<FamilyBasicDataRecorder>(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2))) { if(std::dynamic_pointer_cast<FamilyBasicDataRecorder>(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2))) {
features = (ConsoleFeatures)((int)features | (int)ConsoleFeatures::TapeRecorder); features = (ConsoleFeatures)((int)features | (int)ConsoleFeatures::TapeRecorder);
} }
} }
@ -888,52 +893,71 @@ ConsoleFeatures Console::GetAvailableFeatures()
void Console::InputBarcode(uint64_t barcode, uint32_t digitCount) void Console::InputBarcode(uint64_t barcode, uint32_t digitCount)
{ {
shared_ptr<IBarcodeReader> barcodeReader = std::dynamic_pointer_cast<IBarcodeReader>(_mapper->GetMapperControlDevice()); shared_ptr<BaseMapper> mapper = _mapper;
if(barcodeReader) { shared_ptr<ControlManager> controlManager = controlManager;
barcodeReader->InputBarcode(barcode, digitCount);
if(mapper) {
shared_ptr<IBarcodeReader> barcodeReader = std::dynamic_pointer_cast<IBarcodeReader>(mapper->GetMapperControlDevice());
if(barcodeReader) {
barcodeReader->InputBarcode(barcode, digitCount);
}
} }
barcodeReader = std::dynamic_pointer_cast<IBarcodeReader>(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort)); if(controlManager) {
if(barcodeReader) { shared_ptr<IBarcodeReader> barcodeReader = std::dynamic_pointer_cast<IBarcodeReader>(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort));
barcodeReader->InputBarcode(barcode, digitCount); if(barcodeReader) {
barcodeReader->InputBarcode(barcode, digitCount);
}
} }
} }
void Console::LoadTapeFile(string filepath) void Console::LoadTapeFile(string filepath)
{ {
shared_ptr<FamilyBasicDataRecorder> dataRecorder = std::dynamic_pointer_cast<FamilyBasicDataRecorder>(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2)); shared_ptr<ControlManager> controlManager = _controlManager;
if(dataRecorder) { if(controlManager) {
Console::Pause(); shared_ptr<FamilyBasicDataRecorder> dataRecorder = std::dynamic_pointer_cast<FamilyBasicDataRecorder>(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2));
dataRecorder->LoadFromFile(filepath); if(dataRecorder) {
Console::Resume(); Console::Pause();
dataRecorder->LoadFromFile(filepath);
Console::Resume();
}
} }
} }
void Console::StartRecordingTapeFile(string filepath) void Console::StartRecordingTapeFile(string filepath)
{ {
shared_ptr<FamilyBasicDataRecorder> dataRecorder = std::dynamic_pointer_cast<FamilyBasicDataRecorder>(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2)); shared_ptr<ControlManager> controlManager = _controlManager;
if(dataRecorder) { if(controlManager) {
Console::Pause(); shared_ptr<FamilyBasicDataRecorder> dataRecorder = std::dynamic_pointer_cast<FamilyBasicDataRecorder>(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2));
dataRecorder->StartRecording(filepath); if(dataRecorder) {
Console::Resume(); Console::Pause();
dataRecorder->StartRecording(filepath);
Console::Resume();
}
} }
} }
void Console::StopRecordingTapeFile() void Console::StopRecordingTapeFile()
{ {
shared_ptr<FamilyBasicDataRecorder> dataRecorder = std::dynamic_pointer_cast<FamilyBasicDataRecorder>(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2)); shared_ptr<ControlManager> controlManager = _controlManager;
if(dataRecorder) { if(controlManager) {
Console::Pause(); shared_ptr<FamilyBasicDataRecorder> dataRecorder = std::dynamic_pointer_cast<FamilyBasicDataRecorder>(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2));
dataRecorder->StopRecording(); if(dataRecorder) {
Console::Resume(); Console::Pause();
dataRecorder->StopRecording();
Console::Resume();
}
} }
} }
bool Console::IsRecordingTapeFile() bool Console::IsRecordingTapeFile()
{ {
shared_ptr<FamilyBasicDataRecorder> dataRecorder = std::dynamic_pointer_cast<FamilyBasicDataRecorder>(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2)); shared_ptr<ControlManager> controlManager = _controlManager;
if(dataRecorder) { if(controlManager) {
return dataRecorder->IsRecording(); shared_ptr<FamilyBasicDataRecorder> dataRecorder = std::dynamic_pointer_cast<FamilyBasicDataRecorder>(controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2));
if(dataRecorder) {
return dataRecorder->IsRecording();
}
} }
return false; return false;

View file

@ -41,7 +41,7 @@ class Console
shared_ptr<APU> _apu; shared_ptr<APU> _apu;
shared_ptr<Debugger> _debugger; shared_ptr<Debugger> _debugger;
shared_ptr<BaseMapper> _mapper; shared_ptr<BaseMapper> _mapper;
unique_ptr<ControlManager> _controlManager; shared_ptr<ControlManager> _controlManager;
shared_ptr<MemoryManager> _memoryManager; shared_ptr<MemoryManager> _memoryManager;
shared_ptr<SystemActionManager> _systemActionManager; shared_ptr<SystemActionManager> _systemActionManager;

View file

@ -62,11 +62,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Libretro", "Libretro\Libret
{78FEF1A1-6DF1-4CBB-A373-AE6FA7CE5CE0} = {78FEF1A1-6DF1-4CBB-A373-AE6FA7CE5CE0} {78FEF1A1-6DF1-4CBB-A373-AE6FA7CE5CE0} = {78FEF1A1-6DF1-4CBB-A373-AE6FA7CE5CE0}
EndProjectSection EndProjectSection
EndProject 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 Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU