diff --git a/checkin_notes b/checkin_notes index c0fb3032b4..2568778a86 100644 --- a/checkin_notes +++ b/checkin_notes @@ -6705,3 +6705,13 @@ Rom 25 Feb 2011 / configure.ac version.h + +Rom 14 Mar 2011 + - SCR: Follow the Mac's lead and gracefully exit the Data Management + thread. Preserve the handle to take more drastic actions should + that not work. + + clientscr/ + mac_saver_module.cpp, .h + screensaver.cpp + screensaver_win.cpp, .h diff --git a/clientscr/Mac_Saver_Module.h b/clientscr/Mac_Saver_Module.h index 4d41470111..6a3922ebb7 100644 --- a/clientscr/Mac_Saver_Module.h +++ b/clientscr/Mac_Saver_Module.h @@ -127,7 +127,8 @@ protected: RESULTS results; bool m_bResetCoreState; - bool m_QuitDataManagementProc; + bool m_bQuitDataManagementProc; + bool m_bDataManagementProcStopped; bool m_bV5_GFX_app_is_running; diff --git a/clientscr/mac_saver_module.cpp b/clientscr/mac_saver_module.cpp index 893157736a..b4ce80db5b 100644 --- a/clientscr/mac_saver_module.cpp +++ b/clientscr/mac_saver_module.cpp @@ -162,7 +162,8 @@ CScreensaver::CScreensaver() { m_CoreClientPID = nil; setSSMessageText(0); m_CurrentBannerMessage = 0; - m_QuitDataManagementProc = false; + m_bQuitDataManagementProc = false; + m_bDataManagementProcStopped = false; m_BrandText = "BOINC"; m_hDataManagementThread = NULL; @@ -556,20 +557,19 @@ bool CScreensaver::CreateDataManagementThread() { bool CScreensaver::DestroyDataManagementThread() { - int i; - - m_QuitDataManagementProc = true; // Tell DataManagementProc thread to exit - - for (i=0; i<10; i++) { // Wait up to 1 second for DataManagementProc thread to exit - if (m_hDataManagementThread == NULL) return true; + m_bQuitDataManagementProc = true; // Tell DataManagementProc thread to exit + for (int i=0; i<10; i++) { // Wait up to 1 second for DataManagementProc thread to exit + if (m_bDataManagementProcStopped) return true; boinc_sleep(0.1); } + rpc->close(); // In case DataManagementProc is hung waiting for RPC m_hDataManagementThread = NULL; // Don't delay more if this routine is called again. if (m_hGraphicsApplication) { terminate_screensaver(m_hGraphicsApplication, NULL); m_hGraphicsApplication = 0; } + return true; } diff --git a/clientscr/screensaver.cpp b/clientscr/screensaver.cpp index 4051f960e7..8956c8cdb7 100644 --- a/clientscr/screensaver.cpp +++ b/clientscr/screensaver.cpp @@ -533,7 +533,7 @@ void *CScreensaver::DataManagementProc() // *** // Are we supposed to exit the screensaver? - if (m_QuitDataManagementProc) { // If main thread has requested we exit + if (m_bQuitDataManagementProc) { // If main thread has requested we exit if (m_hGraphicsApplication || graphics_app_result_ptr) { if (m_bDefault_gfx_running) { terminate_default_screensaver(m_hGraphicsApplication); @@ -544,14 +544,14 @@ void *CScreensaver::DataManagementProc() previous_result_ptr = NULL; m_hGraphicsApplication = 0; } - m_hDataManagementThread = NULL; // Tell main thread that we exited - return 0; // Exit the thread + m_bDataManagementProcStopped = true; // Tell main thread that we exited + return 0; // Exit the thread } boinc_sleep(0.25); } // *** - // *** Things that should be run frequently. + // *** Things that should be run less frequently. // *** 1 time per second. // *** @@ -559,7 +559,7 @@ void *CScreensaver::DataManagementProc() if ((m_dwBlankScreen) && (time(0) > m_dwBlankTime)) { BOINCTRACE(_T("CScreensaver::DataManagementProc - Time to blank\n")); SetError(FALSE, SCRAPPERR_SCREENSAVERBLANKED); // Blanked - hide moving BOINC logo - m_QuitDataManagementProc = true; + m_bQuitDataManagementProc = true; continue; // Code above will exit the thread } diff --git a/clientscr/screensaver_win.cpp b/clientscr/screensaver_win.cpp index 8f104c86be..b50d4038bc 100644 --- a/clientscr/screensaver_win.cpp +++ b/clientscr/screensaver_win.cpp @@ -141,7 +141,7 @@ INT WINAPI WinMain( } retval = BOINCSS.Run(); - + // Cleanup any existing screensaver objects and handles BOINCSS.Cleanup(); @@ -199,7 +199,8 @@ CScreensaver::CScreensaver() { m_hDataManagementThread = NULL; m_hGraphicsApplication = NULL; m_bResetCoreState = TRUE; - m_QuitDataManagementProc = FALSE; + m_bQuitDataManagementProc = FALSE; + m_bDataManagementProcStopped = FALSE; memset(&m_running_result, 0, sizeof(m_running_result)); ZeroMemory(m_Monitors, sizeof(m_Monitors)); @@ -282,7 +283,7 @@ HRESULT CScreensaver::Create(HINSTANCE hInstance) { if (rpc == NULL) rpc = new RPC_CLIENT; - // Create the screen saver window(s) + // Create the screen saver window(s) if (m_SaverMode == sm_preview || m_SaverMode == sm_full ) { @@ -388,8 +389,8 @@ HRESULT CScreensaver::Cleanup() { TerminateProcess(m_hGraphicsApplication, 0); m_hGraphicsApplication = NULL; } - if (rpc) { + rpc->close(); delete rpc; rpc = NULL; } @@ -1093,6 +1094,11 @@ BOOL CScreensaver::CreateDataManagementThread() { // Terminate the thread that is used to talk to the daemon. // BOOL CScreensaver::DestroyDataManagementThread() { + m_bQuitDataManagementProc = true; // Tell DataManagementProc thread to exit + for (int i = 0; i < 50; i++) { // Wait up to 5 second for DataManagementProc thread to exit + if (m_bDataManagementProcStopped) return true; + boinc_sleep(0.1); + } if (!TerminateThread(m_hDataManagementThread, 0)) { BOINCTRACE(_T("CScreensaver::DestoryDataManagementThread: Failed to terminate data management thread '%d'\n"), GetLastError()); return FALSE; diff --git a/clientscr/screensaver_win.h b/clientscr/screensaver_win.h index f44aa559dc..b18f00183f 100644 --- a/clientscr/screensaver_win.h +++ b/clientscr/screensaver_win.h @@ -209,7 +209,8 @@ protected: HANDLE m_hDataManagementThread; HANDLE m_hGraphicsApplication; BOOL m_bResetCoreState; - bool m_QuitDataManagementProc; + bool m_bQuitDataManagementProc; + bool m_bDataManagementProcStopped; bool m_bV5_GFX_app_is_running; int m_iLastResultShown; time_t m_tLastResultChangeTime;