From 7a9468edbba5941333ede1e295706e282fa22750 Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Tue, 30 Sep 2008 01:12:49 +0000 Subject: [PATCH] Mgr: Fix 2 async GUI RPCs, also hoping to fix memory leak. svn path=/trunk/boinc/; revision=16091 --- checkin_notes | 14 +++ clientgui/AsyncRPC.cpp | 103 +++++++++++++--------- clientgui/AsyncRPC.h | 8 +- clientgui/MainDocument.cpp | 17 ++-- clientgui/MainDocument.h | 3 + mac_build/boinc.xcodeproj/project.pbxproj | 8 +- 6 files changed, 96 insertions(+), 57 deletions(-) diff --git a/checkin_notes b/checkin_notes index 60a3c5591d..6812c41383 100644 --- a/checkin_notes +++ b/checkin_notes @@ -7842,3 +7842,17 @@ David 29 Sept 2008 lib/ common_defs.h procinfo_unix.cpp + +Charlie 29 Sep 2008 + Mgr: Fix async GUI RPC handling of RPC_GET_PROJECT_STATUS1 and + RPC_GET_SIMPLE_GUI_INFO2, both of which must replace project + structs in the state struct in place. We hope this will + also fix a memory leak. + Mgr: Fix XCode project for browser.C files renamed to browser.cpp. + + clientgui/ + AsyncRPC.cpp,.h + MainDocument.cpp,.h + mac_build/ + boinc.xcodeproj/ + project.pbxproj diff --git a/clientgui/AsyncRPC.cpp b/clientgui/AsyncRPC.cpp index 0aebba35df..f22900d8d1 100755 --- a/clientgui/AsyncRPC.cpp +++ b/clientgui/AsyncRPC.cpp @@ -24,6 +24,7 @@ #include "MainDocument.h" #include "AsyncRPC.h" #include "BOINCBaseFrame.h" +#include "error_numbers.h" // Delay in milliseconds before showing AsyncRPCDlg @@ -195,26 +196,13 @@ int RPCThread::ProcessRPCRequest() { retval = (m_Doc->rpcClient).get_simple_gui_info(*(SIMPLE_GUI_INFO*)(current_request->arg1)); break; case RPC_GET_SIMPLE_GUI_INFO2: - retval = (m_Doc->rpcClient).get_simple_gui_info( - *(CC_STATE*)(current_request->arg1), - *(RESULTS*)(current_request->arg2) - ); + // RPC_GET_SIMPLE_GUI_INFO2 is equivalent to doing both + // RPC_GET_PROJECT_STATUS1 and RPC_GET_RESULTS + retval = (m_Doc->rpcClient).get_project_status(*(PROJECTS*)(current_request->arg1)); + retval = (m_Doc->rpcClient).get_results(*(RESULTS*)(current_request->arg3)); break; case RPC_GET_PROJECT_STATUS1: - if (current_request->exchangeBuf) { - - ((CC_STATE*)(current_request->arg1))->projects.clear(); - - int n = (int)((CC_STATE*)(current_request->exchangeBuf))->projects.size(); - for (int i=0; imaster_url = ((CC_STATE*)(current_request->exchangeBuf))->projects[i]->master_url; - ((CC_STATE*)(current_request->arg1))->projects.push_back(p); - } - - } - retval = (m_Doc->rpcClient).get_project_status(*(CC_STATE*)(current_request->arg1)); + retval = (m_Doc->rpcClient).get_project_status(*(PROJECTS*)(current_request->arg1)); break; case RPC_GET_PROJECT_STATUS2: retval = (m_Doc->rpcClient).get_project_status(*(PROJECTS*)(current_request->arg1)); @@ -595,13 +583,12 @@ void CMainDocument::HandleCompletedRPC() { retval = current_rpc_request.retval; - if (current_rpc_request.completionTime) { - *(current_rpc_request.completionTime) = wxDateTime::Now(); + if (current_rpc_request.rpcType == RPC_TYPE_ASYNC_WITH_REFRESH_AFTER) { + if (!retval) { + m_bNeedRefresh = true; + } } - if (current_rpc_request.resultPtr) { - *(current_rpc_request.resultPtr) = retval; - } - + // Post-processing if (! retval) { switch (current_rpc_request.which_rpc) { @@ -634,22 +621,18 @@ void CMainDocument::HandleCompletedRPC() { } break; case RPC_GET_SIMPLE_GUI_INFO2: - if (current_rpc_request.exchangeBuf && !retval) { - CC_STATE* arg1 = (CC_STATE*)current_rpc_request.arg1; - CC_STATE* exchangeBuf = (CC_STATE*)current_rpc_request.exchangeBuf; - arg1->projects.swap(exchangeBuf->projects); + if (!retval) { + retval = CopyProjectsToStateFile(*(PROJECTS*)(current_rpc_request.arg1), *(CC_STATE*)(current_rpc_request.arg2)); } - if (current_rpc_request.arg3) { - RESULTS* arg2 = (RESULTS*)current_rpc_request.arg2; + if (current_rpc_request.exchangeBuf && !retval) { RESULTS* arg3 = (RESULTS*)current_rpc_request.arg3; - arg2->results.swap(arg3->results); + RESULTS* exchangeBuf = (RESULTS*)current_rpc_request.exchangeBuf; + arg3->results.swap(exchangeBuf->results); } break; case RPC_GET_PROJECT_STATUS1: - if (current_rpc_request.exchangeBuf && !retval) { - CC_STATE* arg1 = (CC_STATE*)current_rpc_request.arg1; - CC_STATE* exchangeBuf = (CC_STATE*)current_rpc_request.exchangeBuf; - arg1->projects.swap(exchangeBuf->projects); + if (!retval) { + retval = CopyProjectsToStateFile(*(PROJECTS*)(current_rpc_request.arg1), *(CC_STATE*)(current_rpc_request.arg2)); } break; case RPC_GET_ALL_PROJECTS_LIST: @@ -716,12 +699,13 @@ void CMainDocument::HandleCompletedRPC() { } } - if (current_rpc_request.rpcType == RPC_TYPE_ASYNC_WITH_REFRESH_AFTER) { - if (!retval) { - m_bNeedRefresh = true; - } + if (current_rpc_request.completionTime) { + *(current_rpc_request.completionTime) = wxDateTime::Now(); } - + if (current_rpc_request.resultPtr) { + *(current_rpc_request.resultPtr) = retval; + } + // 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 @@ -776,6 +760,45 @@ void CMainDocument::HandleCompletedRPC() { } +int CMainDocument::CopyProjectsToStateFile(PROJECTS& p, CC_STATE& state) { + int retval = noErr; + SET_LOCALE sl; + unsigned int i; + PROJECT* state_project = NULL; + + // flag for delete + for (i=0; iflag_for_delete = true; + } + + for (i=0; imaster_url); + if (state_project && (p.projects[i]->master_url == state_project->master_url)) { + // Because the CC_STATE contains several pointers to each element of the + // CC_STATE::projects vector, we must update these elements in place. + state_project->copy(*(p.projects[i])); + state_project->flag_for_delete = false; + } else { + retval = ERR_NOT_FOUND; + } + continue; + } + + // Anything need to be deleted? + if (!retval) { + for (i=0; iflag_for_delete) { + retval = ERR_FILE_MISSING; + } + } + } + + return retval; +} + + IMPLEMENT_CLASS(AsyncRPCDlg, wxDialog) AsyncRPCDlg::AsyncRPCDlg() : wxDialog( NULL, wxID_ANY, wxT(""), wxDefaultPosition ) { diff --git a/clientgui/AsyncRPC.h b/clientgui/AsyncRPC.h index 98bf34bd16..b1631d7667 100644 --- a/clientgui/AsyncRPC.h +++ b/clientgui/AsyncRPC.h @@ -170,10 +170,10 @@ public: { return RPC_Wait(RPC_GET_FILE_TRANSFERS, (void*)&arg1); } int get_simple_gui_info(SIMPLE_GUI_INFO& arg1) { return RPC_Wait(RPC_GET_SIMPLE_GUI_INFO1, (void*)&arg1); } - int get_simple_gui_info(CC_STATE& ccbuf, RESULTS& rbuf) - { return RPC_Wait(RPC_GET_SIMPLE_GUI_INFO2, (void*)&ccbuf, (void*)&rbuf); } - int get_project_status(CC_STATE& arg1) - { return RPC_Wait(RPC_GET_PROJECT_STATUS1, (void*)&arg1); } + int get_simple_gui_info(PROJECTS& arg1, CC_STATE& ccbuf, RESULTS& rbuf) + { return RPC_Wait(RPC_GET_SIMPLE_GUI_INFO2, (void*)&arg1, (void*)&ccbuf, (void*)&rbuf); } + int get_project_status(PROJECTS& arg1, CC_STATE& arg2) + { return RPC_Wait(RPC_GET_PROJECT_STATUS1, (void*)&arg1, (void*)&arg2); } int get_project_status(PROJECTS& arg1) { return RPC_Wait(RPC_GET_PROJECT_STATUS2, (void*)&arg1); } int get_all_projects_list(ALL_PROJECTS_LIST& arg1) diff --git a/clientgui/MainDocument.cpp b/clientgui/MainDocument.cpp index 191919dc2b..eb724141fb 100644 --- a/clientgui/MainDocument.cpp +++ b/clientgui/MainDocument.cpp @@ -808,8 +808,8 @@ void CMainDocument::RunPeriodicRPCs() { if (ts.GetSeconds() > 0) { request.clear(); request.which_rpc = RPC_GET_PROJECT_STATUS1; - request.arg1 = &async_state_buf; - request.exchangeBuf = &state; + request.arg1 = &async_projects_update_buf; + request.arg2 = &state; request.rpcType = RPC_TYPE_ASYNC_WITH_REFRESH_AFTER; request.completionTime = &m_dtProjecStatusTimestamp; request.resultPtr = &m_iGet_project_status1_rpc_result; @@ -905,16 +905,15 @@ void CMainDocument::RunPeriodicRPCs() { } // *********** GET_SIMPLE_GUI_INFO2 ************** - if (currentTabView & VW_SGUI) { wxTimeSpan ts(dtNow - m_dtCachedSimpleGUITimestamp); if (ts.GetSeconds() > 0) { request.clear(); request.which_rpc = RPC_GET_SIMPLE_GUI_INFO2; - request.arg1 = &async_state_buf; - request.exchangeBuf = &state; - request.arg2 = &async_results_buf; - request.arg3 = &results; + request.arg1 = &async_projects_update_buf; + request.arg2 = &state; + request.arg3 = &async_results_buf; + request.exchangeBuf = &results; request.rpcType = RPC_TYPE_ASYNC_WITH_REFRESH_AFTER; request.completionTime = &m_dtCachedSimpleGUITimestamp; request.resultPtr = &m_iGet_simple_gui2_rpc_result; @@ -1066,7 +1065,7 @@ int CMainDocument::CachedProjectStatusUpdate(bool bForce) { if (bForce) { m_dtProjecStatusTimestamp = wxDateTime::Now(); - m_iGet_project_status1_rpc_result = rpc.get_project_status(state); + m_iGet_project_status1_rpc_result = rpc.get_project_status(async_projects_update_buf, state); } if (m_iGet_project_status1_rpc_result) { @@ -1939,7 +1938,7 @@ int CMainDocument::CachedSimpleGUIUpdate(bool bForce) { if (bForce) { m_dtCachedSimpleGUITimestamp = wxDateTime::Now(); - m_iGet_simple_gui2_rpc_result = rpc.get_simple_gui_info(state, results); + m_iGet_simple_gui2_rpc_result = rpc.get_simple_gui_info(async_projects_update_buf, state, results); } if (m_iGet_simple_gui2_rpc_result) { diff --git a/clientgui/MainDocument.h b/clientgui/MainDocument.h index 53f374f185..a3dbfa396c 100644 --- a/clientgui/MainDocument.h +++ b/clientgui/MainDocument.h @@ -156,6 +156,8 @@ public: CBOINCClientManager* m_pClientManager; AsyncRPC rpc; RPC_CLIENT rpcClient; + PROJECTS async_projects_update_buf; + CC_STATE state; CC_STATE async_state_buf; int m_iGet_state_rpc_result; @@ -184,6 +186,7 @@ public: bool m_bNeedRefresh; private: + int CopyProjectsToStateFile(PROJECTS& p, CC_STATE& state); ASYNC_RPC_REQUEST current_rpc_request; AsyncRPCDlg* m_RPCWaitDlg; std::vector RPC_requests; diff --git a/mac_build/boinc.xcodeproj/project.pbxproj b/mac_build/boinc.xcodeproj/project.pbxproj index eeda4eda48..1d00b80563 100755 --- a/mac_build/boinc.xcodeproj/project.pbxproj +++ b/mac_build/boinc.xcodeproj/project.pbxproj @@ -164,7 +164,7 @@ DD4C561A0AD389A2009E23C6 /* sg_ImageButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD4C560E0AD389A2009E23C6 /* sg_ImageButton.cpp */; }; DD4C561C0AD389A2009E23C6 /* sg_ProgressBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD4C56100AD389A2009E23C6 /* sg_ProgressBar.cpp */; }; DD4C561E0AD389A2009E23C6 /* sg_SGUIListControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD4C56120AD389A2009E23C6 /* sg_SGUIListControl.cpp */; }; - DD4E704C0BCDAC360010A522 /* browser.C in Sources */ = {isa = PBXBuildFile; fileRef = DD4E70490BCDAC360010A522 /* browser.C */; }; + DD4E704C0BCDAC360010A522 /* browser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD4E70490BCDAC360010A522 /* browser.cpp */; }; DD4EC65A08A0A7AF009AA08F /* gui_rpc_client_ops.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD73E34E08A0694000656EB1 /* gui_rpc_client_ops.cpp */; }; DD4EC65B08A0A83F009AA08F /* gui_rpc_client_print.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD73E34F08A0694100656EB1 /* gui_rpc_client_print.cpp */; }; DD51DC8F0A4943A300BD24E6 /* check_security.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD6617870A3FFD8C00FFEBEB /* check_security.cpp */; }; @@ -631,7 +631,7 @@ DD4C56110AD389A2009E23C6 /* sg_ProgressBar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sg_ProgressBar.h; path = ../clientgui/sg_ProgressBar.h; sourceTree = SOURCE_ROOT; }; DD4C56120AD389A2009E23C6 /* sg_SGUIListControl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sg_SGUIListControl.cpp; path = ../clientgui/sg_SGUIListControl.cpp; sourceTree = SOURCE_ROOT; }; DD4C56130AD389A2009E23C6 /* sg_SGUIListControl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sg_SGUIListControl.h; path = ../clientgui/sg_SGUIListControl.h; sourceTree = SOURCE_ROOT; }; - DD4E70490BCDAC360010A522 /* browser.C */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = browser.C; path = ../clientgui/browser.C; sourceTree = SOURCE_ROOT; }; + DD4E70490BCDAC360010A522 /* browser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = browser.cpp; sourceTree = ""; }; DD4E704A0BCDAC360010A522 /* browser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = browser.h; path = ../clientgui/browser.h; sourceTree = SOURCE_ROOT; }; DD4EC60F08A0A083009AA08F /* texture.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = texture.cpp; sourceTree = ""; }; DD4EC61008A0A083009AA08F /* texture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = texture.h; path = ../api/texture.h; sourceTree = SOURCE_ROOT; }; @@ -1184,7 +1184,7 @@ DD81C40607C5D1020098A04D /* BOINCTaskCtrl.cpp */, DD81C43807C5D2240098A04D /* BOINCTaskCtrl.h */, DD58C43608F3347D00C1DF66 /* BOINCWizards.h */, - DD4E70490BCDAC360010A522 /* browser.C */, + DD4E70490BCDAC360010A522 /* browser.cpp */, DD4E704A0BCDAC360010A522 /* browser.h */, DDCE78220A70BD29008218B6 /* common */, DD58C43708F3347D00C1DF66 /* CompletionErrorPage.cpp */, @@ -2284,7 +2284,7 @@ DD7DD7C90B8BFD4800B11279 /* ViewMessages.cpp in Sources */, DD7BF7E60B8E7B6C00A009F7 /* str_util.cpp in Sources */, DD205A1A0BAF596E0008D473 /* ProjectListCtrl.cpp in Sources */, - DD4E704C0BCDAC360010A522 /* browser.C in Sources */, + DD4E704C0BCDAC360010A522 /* browser.cpp in Sources */, DDA6BD210BD4551F008F7921 /* mac_backtrace.cpp in Sources */, DDA6BD230BD4551F008F7921 /* QBacktrace.c in Sources */, DDA6BD250BD4551F008F7921 /* QCrashReport.c in Sources */,