From 022550a43b9e7ccdeaaec1ee024f92c4efd9c00c Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sat, 12 Jan 2019 12:53:18 +0100 Subject: [PATCH] cellOskDialog: use atomic_op for state operations --- rpcs3/Emu/Cell/Modules/cellOskDialog.cpp | 41 ++++++++++++++++++------ 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp index 70a61ff9ed..0c7416885a 100644 --- a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp +++ b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp @@ -89,15 +89,22 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr dia { const auto osk = wptr.lock(); - if (osk->state.load() == OskDialogState::Abort) + if (osk->state.atomic_op([&](OskDialogState& state) + { + if (state == OskDialogState::Abort) + { + return true; + } + + state = OskDialogState::Close; + return false; + })) { pad::SetIntercepted(false); sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0); return; } - osk->state = OskDialogState::Close; - const bool accepted = status == CELL_MSGDIALOG_BUTTON_OK; if (accepted) @@ -301,20 +308,36 @@ error_code cellOskDialogAbort() const auto osk = fxm::get(); - // Check for open dialog. In this case the dialog is only "Open" if it was not aborted before. - if (!osk || osk->state.load() == OskDialogState::Abort) + if (!osk) { return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED; } - // If the dialog has the Open state then it is in use. Only dialogs with the Close state can be aborted. - if (osk->state.load() == OskDialogState::Open) + const s32 result = osk->state.atomic_op([](OskDialogState& state) { - return CELL_SYSUTIL_ERROR_BUSY; + // Check for open dialog. In this case the dialog is only "Open" if it was not aborted before. + if (state == OskDialogState::Abort) + { + return static_cast(CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED); + } + + // If the dialog has the Open state then it is in use. Only dialogs with the Close state can be aborted. + if (state == OskDialogState::Open) + { + return static_cast(CELL_SYSUTIL_ERROR_BUSY); + } + + state = OskDialogState::Abort; + + return static_cast(CELL_OK); + }); + + if (result != CELL_OK) + { + return result; } osk->osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_ABORT; - osk->state = OskDialogState::Abort; osk->Close(false); return CELL_OK;