diff --git a/checkin_notes b/checkin_notes index e6156f4392..3d437c5d6d 100644 --- a/checkin_notes +++ b/checkin_notes @@ -7556,3 +7556,14 @@ David 18 Sept 2008 gui_rpc_server_ops.C clientgui/ AsyncRPC.cpp,h + +Charlie 18 Sep 2008 + Mgr: The system handles timer events during modal dialogs, such as + while the RPC Wait dialog is shown. This may cause unintended + recursion and repeatedly posting the same RPC requests from + timer routines while waitung for the first one to complete, so + ignore timer events during that dialog. + + clientgui/ + BOINCBaseFrame.cpp + MainDocument.cpp,.h diff --git a/clientgui/BOINCBaseFrame.cpp b/clientgui/BOINCBaseFrame.cpp index 8d3caed4a7..086fdd0d33 100644 --- a/clientgui/BOINCBaseFrame.cpp +++ b/clientgui/BOINCBaseFrame.cpp @@ -170,6 +170,11 @@ void CBOINCBaseFrame::OnDocumentPoll(wxTimerEvent& WXUNUSED(event)) { wxASSERT(pDoc); wxASSERT(wxDynamicCast(pDoc, CMainDocument)); + // Timer events are handled while the RPC Wait dialog is shown + // which may cause unintended recursion and repeatedly posting + // the same RPC requests from timer routines. + if (pDoc->WaitingForRPC()) return; + if (!bAlreadyRunOnce && m_pDocumentPollTimer->IsRunning()) { // Complete any remaining initialization that has to happen after we are up // and running @@ -194,7 +199,10 @@ void CBOINCBaseFrame::OnAlertPoll(wxTimerEvent& WXUNUSED(event)) { // Check to see if there is anything that we need to do from the // dial up user perspective. if (pDoc && m_pDialupManager) { - if (pDoc->IsConnected()) { + // Timer events are handled while the RPC Wait dialog is shown + // which may cause unintended recursion and repeatedly posting + // the same RPC requests from timer routines. + if (pDoc->IsConnected() && !pDoc->WaitingForRPC()) { m_pDialupManager->OnPoll(); } } @@ -595,13 +603,21 @@ void CBOINCBaseFrame::ShowNotCurrentlyConnectedAlert() { void CBOINCBaseFrame::StartTimers() { wxASSERT(m_pAlertPollTimer); + wxASSERT(m_pPeriodicRPCTimer); + wxASSERT(m_pDocumentPollTimer); m_pAlertPollTimer->Start(); + m_pPeriodicRPCTimer->Start(); + m_pDocumentPollTimer->Start(); } void CBOINCBaseFrame::StopTimers() { wxASSERT(m_pAlertPollTimer); + wxASSERT(m_pPeriodicRPCTimer); + wxASSERT(m_pDocumentPollTimer); m_pAlertPollTimer->Stop(); + m_pPeriodicRPCTimer->Stop(); + m_pDocumentPollTimer->Stop(); } diff --git a/clientgui/MainDocument.cpp b/clientgui/MainDocument.cpp index a04e215d23..0f0eb1dbae 100644 --- a/clientgui/MainDocument.cpp +++ b/clientgui/MainDocument.cpp @@ -722,6 +722,11 @@ void CMainDocument::RefreshRPCs() { void CMainDocument::RunPeriodicRPCs() { ASYNC_RPC_REQUEST request; + // Timer events are handled while the RPC Wait dialog is shown + // which may cause unintended recursion and repeatedly posting + // the same RPC requests from timer routines. + if (WaitingForRPC()) return; + CBOINCBaseFrame* pFrame = wxGetApp().GetFrame(); if (!pFrame) return; wxASSERT(wxDynamicCast(pFrame, CBOINCBaseFrame)); diff --git a/clientgui/MainDocument.h b/clientgui/MainDocument.h index 2f7fac5ba8..1958f7bc32 100644 --- a/clientgui/MainDocument.h +++ b/clientgui/MainDocument.h @@ -176,7 +176,8 @@ public: int RequestRPC(ASYNC_RPC_REQUEST& request, bool hasPriority = false); void OnRPCComplete(CRPCFinishedEvent& event); void HandleCompletedRPC(); - ASYNC_RPC_REQUEST* GetCurrentRPCRequest() { return ¤t_rpc_request; }; + ASYNC_RPC_REQUEST* GetCurrentRPCRequest() { return ¤t_rpc_request; } + bool WaitingForRPC() { return m_bWaitingForRPC; } // void TestAsyncRPC(); // For testing Async RPCs RPCThread* m_RPCThread; wxCriticalSection m_critsect;