Fixed random segfaults and deadlocks caused by the wx status bar handling.

Moved status bar update to the gui thread and added a new event type called
BX_ASYNC_EVT_STATUSBAR to invoke it. Changed size and style of the status bar
items.
This commit is contained in:
Volker Ruppert 2020-07-10 08:13:17 +00:00
parent 650d8d919a
commit a28257429f
4 changed files with 52 additions and 28 deletions

View File

@ -283,6 +283,7 @@ typedef enum {
BX_ASYNC_EVT_DBG_MSG, // simulator -> CI
BX_ASYNC_EVT_VALUE_CHANGED, // simulator -> CI
BX_ASYNC_EVT_TOOLBAR, // CI -> simulator
BX_ASYNC_EVT_STATUSBAR, // simulator -> CI
BX_ASYNC_EVT_REFRESH, // simulator -> CI
BX_ASYNC_EVT_QUIT_SIM // simulator -> CI
} BxEventType;
@ -440,7 +441,7 @@ typedef struct {
// Event type: BX_EVT_TOOLBAR
// Event type: BX_ASYNC_EVT_TOOLBAR
// Asynchronous event from the VGAW to the simulator, sent when the user
// clicks on a toolbar button. This may one day become something more
// general, like a command event, but at the moment it's only needed for
@ -451,6 +452,14 @@ typedef struct {
// pressed. on=false means it is not pressed.
} BxToolbarEvent;
// Event type: BX_ASYNC_EVT_STATUSAR
typedef struct {
int element;
char *text;
bx_bool active;
bx_bool w;
} BxStatusbarEvent;
// The BxEvent structure should be used for all events. Every event has
// a type and a spot for a return code (only used for synchronous events).
typedef struct {
@ -462,6 +471,7 @@ typedef struct {
BxParamEvent param;
BxLogMsgEvent logmsg;
BxToolbarEvent toolbar;
BxStatusbarEvent statbar;
BxDebugCommand debugcmd;
} u;
} BxEvent;

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2019 The Bochs Project
// Copyright (C) 2002-2020 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -1177,24 +1177,15 @@ void bx_wx_gui_c::handle_events(void)
void bx_wx_gui_c::statusbar_setitem_specific(int element, bx_bool active, bx_bool w)
{
#if defined(__WXMSW__)
char status_text[10];
#endif
wxMutexGuiEnter();
if (active) {
#if defined(__WXMSW__)
status_text[0] = 9;
strcpy(status_text+1, statusitem[element].text);
theFrame->SetStatusText(status_text, element+1);
#else
theFrame->SetStatusText(wxString(statusitem[element].text, wxConvUTF8),
element+1);
#endif
} else {
theFrame->SetStatusText(wxT(""), element+1);
}
wxMutexGuiLeave();
char *sbtext = new char[strlen(statusitem[element].text) + 1];
strcpy(sbtext, statusitem[element].text);
BxEvent *event = new BxEvent;
event->type = BX_ASYNC_EVT_STATUSBAR;
event->u.statbar.element = element;
event->u.statbar.text = sbtext;
event->u.statbar.active = active;
event->u.statbar.w = w;
SIM->sim_to_ci_event(event);
}
void bx_wx_gui_c::flush(void)

View File

@ -397,11 +397,6 @@ END_EVENT_TABLE()
// | Pause/Resume |
// | Stop |
// +----------------------|
// - Debug
// +----------------------|
// | Show CPU |
// | Debug Console |
// +----------------------|
// - Event Log
// +----------------------+
// | View |
@ -458,7 +453,6 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
menuSimulate->Append(ID_Simulate_Start, wxT("&Start..."));
menuSimulate->Append(ID_Simulate_PauseResume, wxT("&Pause..."));
menuSimulate->Append(ID_Simulate_Stop, wxT("S&top..."));
menuSimulate->AppendSeparator();
menuSimulate->Enable(ID_Simulate_PauseResume, FALSE);
menuSimulate->Enable(ID_Simulate_Stop, FALSE);
@ -488,8 +482,12 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
CreateStatusBar();
wxStatusBar *sb = GetStatusBar();
sb->SetFieldsCount(12);
const int sbwidth[12] = {160, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, -1};
const int sbwidth[12] = {160, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, -1};
sb->SetStatusWidths(12, sbwidth);
const int sbstyle[12] = {wxSB_SUNKEN, wxSB_SUNKEN, wxSB_SUNKEN, wxSB_SUNKEN,
wxSB_SUNKEN, wxSB_SUNKEN, wxSB_SUNKEN, wxSB_SUNKEN,
wxSB_SUNKEN, wxSB_SUNKEN, wxSB_SUNKEN, wxSB_NORMAL};
sb->SetStatusStyles(12, sbstyle);
CreateToolBar(wxNO_BORDER|wxHORIZONTAL|wxTB_FLAT);
bxToolBar = GetToolBar();
@ -1102,6 +1100,27 @@ int MyFrame::HandleAskParam(BxEvent *event)
return -1; // could not display
}
void MyFrame::StatusbarUpdate(BxEvent *event)
{
int element = event->u.statbar.element;
#if defined(__WXMSW__)
char status_text[10];
#endif
if (event->u.statbar.active) {
#if defined(__WXMSW__)
status_text[0] = 9;
strcpy(status_text+1, event->u.statbar.text);
SetStatusText(status_text, element+1);
#else
SetStatusText(wxString(event->u.statbar.text, wxConvUTF8), element+1);
#endif
} else {
SetStatusText(wxT(""), element+1);
}
delete [] event->u.statbar.text;
}
// This is called from the wxWidgets GUI thread, when a Sim2CI event
// is found. (It got there via wxPostEvent in SiminterfaceCallback2, which is
// executed in the simulator Thread.)
@ -1132,6 +1151,9 @@ void MyFrame::OnSim2CIEvent(wxCommandEvent& event)
wxMessageBox(wxT("Bochs simulation has stopped."), wxT("Bochs Stopped"),
wxOK | wxICON_INFORMATION, this);
break;
case BX_ASYNC_EVT_STATUSBAR:
StatusbarUpdate(be);
break;
default:
wxLogDebug(wxT("OnSim2CIEvent: event type %d ignored"), (int)be->type);
if (!BX_EVT_IS_ASYNC(be->type)) {

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2017 The Bochs Project
// Copyright (C) 2002-2020 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -207,6 +207,7 @@ public:
void OnToolbarClick(wxCommandEvent& event);
int HandleAskParam(BxEvent *event);
int HandleAskParamString(bx_param_string_c *param);
void StatusbarUpdate(BxEvent *event);
// called from the sim thread's OnExit() method.
void OnSimThreadExit();