From 573c33bb5c41fe30f37c02989b78e7390f58187f Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Sun, 14 Sep 2008 10:08:11 +0000 Subject: [PATCH] MGR: async GUI RPCs: Finish processing event handling for each RPC before starting next RPC svn path=/trunk/boinc/; revision=15997 --- checkin_notes | 10 ++++++ clientgui/AsyncRPC.cpp | 55 ++++++++++++++++----------------- clientgui/sg_BoincSimpleGUI.cpp | 11 ------- 3 files changed, 37 insertions(+), 39 deletions(-) diff --git a/checkin_notes b/checkin_notes index f7cde67641..e8f09c332c 100644 --- a/checkin_notes +++ b/checkin_notes @@ -7424,3 +7424,13 @@ Charlie 13 Sep 2008 BOINCBaseView.cpp ViewProjects.cpp ViewWork.cpp + +Charlie 14 Sep 2008 + - MGR: async GUI RPCs: Finish processing event handling for each RPC + before starting next RPC, because the 2 RPCs may write into the + same buffer, especially when switching between Simple and Advanced + GUIs. + + clientgui/ + AsyncRPC.cpp + sg_BoincSimpleGUI.cpp diff --git a/clientgui/AsyncRPC.cpp b/clientgui/AsyncRPC.cpp index 047fc7d3a7..018d5ba8f8 100755 --- a/clientgui/AsyncRPC.cpp +++ b/clientgui/AsyncRPC.cpp @@ -711,12 +711,35 @@ void CMainDocument::HandleCompletedRPC() { } } - wxEvent *crr_event = current_rpc_request.event; - wxEvtHandler *crr_eventHandler = current_rpc_request.eventHandler; - + // We must call ProcessEvent() rather than AddPendingEvent() here to + // guarantee integrity of data when other events are handled (such as + // Abort, Suspend/Resume, Show Graphics, Update, Detach, Reset, No + // New Work, etc.) Otherwise, if one of those events is pending it + // might be processed first, and the data in the selected rows may not + // match the data which the user selected if any rows were added or + // deleted due to the RPC. + // The refresh event called here adjusts the selections to fix any + // such mismatch before other pending events are processed. + if ( (current_rpc_request.event) && (current_rpc_request.event != (wxEvent*)-1) ) { + if (!retval) { + if (current_rpc_request.eventHandler) { + current_rpc_request.eventHandler->ProcessEvent(*current_rpc_request.event); + } else { + if (pFrame) { + wxASSERT(wxDynamicCast(pFrame, CBOINCBaseFrame)); + pFrame->ProcessEvent(*current_rpc_request.event); + } + } + } + delete current_rpc_request.event; + current_rpc_request.event = NULL; + } + current_rpc_request.clear(); - // Start the next RPC request. + // Start the next RPC request. + // We can't start this until finished processing the previous RPC's + // event because the two requests may write into the same buffer. if (RPC_requests.size() > 0) { // Make sure activation is an atomic operation RPC_requests[0].isActive = false; @@ -735,30 +758,6 @@ void CMainDocument::HandleCompletedRPC() { } #endif // ! __WXMSW__ // Deadlocks on Windows } - - // We must call ProcessEvent() rather than AddPendingEvent() here to - // guarantee integrity of data when other events are handled (such as - // Abort, Suspend/Resume, Show Graphics, Update, Detach, Reset, No - // New Work, etc.) Otherwise, if one of those events is pending it - // might be processed first, and the data in the selected rows may not - // match the data which the user selected if any rows were added or - // deleted due to the RPC. - // The refresh event called here adjusts the selections to fix any - // such mismatch before other pending events are processed. - if ( (crr_event) && (crr_event != (wxEvent*)-1) ) { - if (!retval) { - if (crr_eventHandler) { - crr_eventHandler->ProcessEvent(*crr_event); - } else { - if (pFrame) { - wxASSERT(wxDynamicCast(pFrame, CBOINCBaseFrame)); - pFrame->ProcessEvent(*crr_event); - } - } - } - delete crr_event; - crr_event = NULL; - } } diff --git a/clientgui/sg_BoincSimpleGUI.cpp b/clientgui/sg_BoincSimpleGUI.cpp index 68da7ac853..59d0c57289 100644 --- a/clientgui/sg_BoincSimpleGUI.cpp +++ b/clientgui/sg_BoincSimpleGUI.cpp @@ -81,11 +81,6 @@ CSimpleFrame::CSimpleFrame(wxString title, wxIcon* icon, wxIcon* icon32) : { wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::CSimpleFrame - Overloaded Constructor Function Begin")); - CMainDocument* pDoc = wxGetApp().GetDocument(); - - wxASSERT(pDoc); - wxASSERT(wxDynamicCast(pDoc, CMainDocument)); - RestoreState(); // Initialize Application @@ -195,9 +190,6 @@ CSimpleFrame::CSimpleFrame(wxString title, wxIcon* icon, wxIcon* icon32) : m_pAccelTable = new wxAcceleratorTable(1, m_Shortcuts); SetAcceleratorTable(*m_pAccelTable); - pDoc->CachedSimpleGUIUpdate(true); - pDoc->CachedProjectStatusUpdate(true); - dlgMsgsPtr = NULL; m_pBackgroundPanel = new CSimplePanel(this); } @@ -422,9 +414,7 @@ void CSimpleFrame::OnConnect(CFrameEvent& WXUNUSED(event)) { wxASSERT(wxDynamicCast(pDoc, CMainDocument)); pDoc->ForceCacheUpdate(); - pDoc->RefreshRPCs(); pDoc->GetCoreClientStatus(status, true); - pDoc->CachedProjectStatusUpdate(); // If we are connected to the localhost, run a really quick screensaver // test to trigger a firewall popup. @@ -476,7 +466,6 @@ IMPLEMENT_DYNAMIC_CLASS(CSimplePanel, wxPanel) BEGIN_EVENT_TABLE(CSimplePanel, wxPanel) EVT_SIZE(CSimplePanel::OnSize) EVT_ERASE_BACKGROUND(CSimplePanel::OnEraseBackground) -// EVT_TIMER(ID_SIMPLEFRAMERENDERTIMER, CSimplePanel::OnFrameRender) END_EVENT_TABLE()