Mgr: ignore timer events during RPC Wait dialog to prevent unintended recursion and crashes

svn path=/trunk/boinc/; revision=16024
This commit is contained in:
Charlie Fenton 2008-09-19 06:50:25 +00:00
parent d0102629e7
commit 9758c47ffe
4 changed files with 35 additions and 2 deletions

View File

@ -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

View File

@ -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();
}

View File

@ -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));

View File

@ -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 &current_rpc_request; };
ASYNC_RPC_REQUEST* GetCurrentRPCRequest() { return &current_rpc_request; }
bool WaitingForRPC() { return m_bWaitingForRPC; }
// void TestAsyncRPC(); // For testing Async RPCs
RPCThread* m_RPCThread;
wxCriticalSection m_critsect;