mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-12 13:13:43 +00:00
cellMsgDialog race condition fixed
This commit is contained in:
parent
be2f993155
commit
3d665148ca
@ -14,7 +14,6 @@ extern u64 get_system_time();
|
||||
std::unique_ptr<MsgDialogInstance> g_msg_dialog;
|
||||
|
||||
MsgDialogInstance::MsgDialogInstance()
|
||||
: state(msgDialogNone)
|
||||
{
|
||||
}
|
||||
|
||||
@ -83,7 +82,7 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialog
|
||||
}
|
||||
|
||||
MsgDialogState old = msgDialogNone;
|
||||
if (!g_msg_dialog->state.compare_exchange_strong(old, msgDialogOpen))
|
||||
if (!g_msg_dialog->state.compare_exchange_strong(old, msgDialogInit))
|
||||
{
|
||||
return CELL_SYSUTIL_ERROR_BUSY;
|
||||
}
|
||||
@ -105,33 +104,45 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialog
|
||||
|
||||
std::string msg = msgString.get_ptr();
|
||||
|
||||
switch (type & CELL_MSGDIALOG_TYPE_SE_TYPE)
|
||||
{
|
||||
case CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL: cellSysutil.Warning("%s", msg); break;
|
||||
case CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR: cellSysutil.Error("%s", msg); break;
|
||||
}
|
||||
|
||||
g_msg_dialog->status = CELL_MSGDIALOG_BUTTON_NONE;
|
||||
|
||||
CallAfter([type, msg]()
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
g_msg_dialog->state.exchange(msgDialogNone);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
g_msg_dialog->Create(type, msg);
|
||||
|
||||
g_msg_dialog->state.exchange(msgDialogOpen);
|
||||
});
|
||||
|
||||
while (g_msg_dialog->state == msgDialogInit)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
if (g_msg_dialog->state != msgDialogNone)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
CHECK_EMU_STATUS;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
}
|
||||
|
||||
thread_t(WRAP_EXPR("MsgDialog Thread"), [=]()
|
||||
{
|
||||
switch (type & CELL_MSGDIALOG_TYPE_SE_TYPE)
|
||||
{
|
||||
case CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL: cellSysutil.Warning("%s", msg); break;
|
||||
case CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR: cellSysutil.Error("%s", msg); break;
|
||||
}
|
||||
|
||||
g_msg_dialog->status = CELL_MSGDIALOG_BUTTON_NONE;
|
||||
|
||||
volatile bool m_signal = false;
|
||||
CallAfter([type, msg, &m_signal]()
|
||||
{
|
||||
if (Emu.IsStopped()) return;
|
||||
|
||||
g_msg_dialog->Create(type, msg);
|
||||
|
||||
m_signal = true;
|
||||
});
|
||||
|
||||
while (!m_signal)
|
||||
{
|
||||
CHECK_EMU_STATUS;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
}
|
||||
|
||||
while (g_msg_dialog->state == msgDialogOpen || (s64)(get_system_time() - g_msg_dialog->wait_until) < 0)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
@ -142,7 +153,7 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialog
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
}
|
||||
|
||||
if (callback && (g_msg_dialog->state != msgDialogAbort))
|
||||
if (callback && g_msg_dialog->state != msgDialogAbort)
|
||||
{
|
||||
const s32 status = g_msg_dialog->status;
|
||||
|
||||
@ -350,6 +361,8 @@ s32 cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta)
|
||||
|
||||
void cellSysutil_MsgDialog_init()
|
||||
{
|
||||
g_msg_dialog->state = msgDialogNone;
|
||||
|
||||
REG_FUNC(cellSysutil, cellMsgDialogOpen2);
|
||||
REG_FUNC(cellSysutil, cellMsgDialogOpenErrorCode);
|
||||
REG_FUNC(cellSysutil, cellMsgDialogProgressBarSetMsg);
|
||||
|
@ -82,11 +82,12 @@ enum : s32
|
||||
CELL_MSGDIALOG_BUTTON_ESCAPE = 3,
|
||||
};
|
||||
|
||||
typedef void(CellMsgDialogCallback)(s32 buttonType, vm::ptr<void> userData);
|
||||
using CellMsgDialogCallback = void(s32 buttonType, vm::ptr<void> userData);
|
||||
|
||||
enum MsgDialogState
|
||||
{
|
||||
msgDialogNone,
|
||||
msgDialogInit,
|
||||
msgDialogOpen,
|
||||
msgDialogClose,
|
||||
msgDialogAbort,
|
||||
@ -96,9 +97,9 @@ struct MsgDialogInstance
|
||||
{
|
||||
std::atomic<MsgDialogState> state;
|
||||
|
||||
s32 status = 0;
|
||||
u64 wait_until = 0;
|
||||
u32 progress_bar_count = 0;
|
||||
s32 status;
|
||||
u64 wait_until;
|
||||
u32 progress_bar_count;
|
||||
|
||||
MsgDialogInstance();
|
||||
virtual ~MsgDialogInstance() = default;
|
||||
|
@ -17,27 +17,27 @@ void MsgDialogFrame::Create(u32 type, std::string msg)
|
||||
m_button_yes = nullptr;
|
||||
m_button_no = nullptr;
|
||||
|
||||
m_dialog = new wxDialog(parent, wxID_ANY, type & CELL_MSGDIALOG_TYPE_SE_TYPE ? "" : "Error", wxDefaultPosition, wxDefaultSize);
|
||||
m_dialog = std::make_unique<wxDialog>(parent, wxID_ANY, type & CELL_MSGDIALOG_TYPE_SE_TYPE ? "" : "Error", wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
m_dialog->SetExtraStyle(m_dialog->GetExtraStyle() | wxWS_EX_TRANSIENT);
|
||||
m_dialog->SetTransparent(127 + (type & CELL_MSGDIALOG_TYPE_BG) * (128 / CELL_MSGDIALOG_TYPE_BG_INVISIBLE));
|
||||
|
||||
m_sizer1 = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_text = new wxStaticText(m_dialog, wxID_ANY, wxString(msg.c_str(), wxConvUTF8));
|
||||
m_text = new wxStaticText(m_dialog.get(), wxID_ANY, wxString(msg.c_str(), wxConvUTF8));
|
||||
m_sizer1->Add(m_text, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16);
|
||||
|
||||
switch (type & CELL_MSGDIALOG_TYPE_PROGRESSBAR)
|
||||
{
|
||||
case CELL_MSGDIALOG_TYPE_PROGRESSBAR_DOUBLE:
|
||||
m_gauge2 = new wxGauge(m_dialog, wxID_ANY, 100, wxDefaultPosition, wxSize(300, -1), wxGA_HORIZONTAL | wxGA_SMOOTH);
|
||||
m_text2 = new wxStaticText(m_dialog, wxID_ANY, "");
|
||||
m_gauge2 = new wxGauge(m_dialog.get(), wxID_ANY, 100, wxDefaultPosition, wxSize(300, -1), wxGA_HORIZONTAL | wxGA_SMOOTH);
|
||||
m_text2 = new wxStaticText(m_dialog.get(), wxID_ANY, "");
|
||||
m_text2->SetAutoLayout(true);
|
||||
// fallthrough
|
||||
|
||||
case CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE:
|
||||
m_gauge1 = new wxGauge(m_dialog, wxID_ANY, 100, wxDefaultPosition, wxSize(300, -1), wxGA_HORIZONTAL | wxGA_SMOOTH);
|
||||
m_text1 = new wxStaticText(m_dialog, wxID_ANY, "");
|
||||
m_gauge1 = new wxGauge(m_dialog.get(), wxID_ANY, 100, wxDefaultPosition, wxSize(300, -1), wxGA_HORIZONTAL | wxGA_SMOOTH);
|
||||
m_text1 = new wxStaticText(m_dialog.get(), wxID_ANY, "");
|
||||
m_text1->SetAutoLayout(true);
|
||||
}
|
||||
|
||||
@ -59,9 +59,9 @@ void MsgDialogFrame::Create(u32 type, std::string msg)
|
||||
|
||||
if (type & CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO)
|
||||
{
|
||||
m_button_yes = new wxButton(m_dialog, wxID_YES);
|
||||
m_button_yes = new wxButton(m_dialog.get(), wxID_YES);
|
||||
m_buttons->Add(m_button_yes, 0, wxALIGN_CENTER_HORIZONTAL | wxRIGHT, 8);
|
||||
m_button_no = new wxButton(m_dialog, wxID_NO);
|
||||
m_button_no = new wxButton(m_dialog.get(), wxID_NO);
|
||||
m_buttons->Add(m_button_no, 0, wxALIGN_CENTER_HORIZONTAL, 16);
|
||||
|
||||
if ((type & CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR) == CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_NO)
|
||||
@ -78,7 +78,7 @@ void MsgDialogFrame::Create(u32 type, std::string msg)
|
||||
|
||||
if (type & CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK)
|
||||
{
|
||||
m_button_ok = new wxButton(m_dialog, wxID_OK);
|
||||
m_button_ok = new wxButton(m_dialog.get(), wxID_OK);
|
||||
m_buttons->Add(m_button_ok, 0, wxALIGN_CENTER_HORIZONTAL, 16);
|
||||
|
||||
if ((type & CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR) == CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_OK)
|
||||
@ -119,8 +119,7 @@ void MsgDialogFrame::Create(u32 type, std::string msg)
|
||||
|
||||
void MsgDialogFrame::Destroy()
|
||||
{
|
||||
delete m_dialog;
|
||||
m_dialog = nullptr;
|
||||
m_dialog.reset();
|
||||
}
|
||||
|
||||
void MsgDialogFrame::ProgressBarSetMsg(u32 index, std::string msg)
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
class MsgDialogFrame : public MsgDialogInstance
|
||||
{
|
||||
wxDialog* m_dialog;
|
||||
std::unique_ptr<wxDialog> m_dialog;
|
||||
wxGauge* m_gauge1;
|
||||
wxGauge* m_gauge2;
|
||||
wxStaticText* m_text1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user