From 2c89b4103e46e11a2d5f8776943a46635ded97f4 Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Thu, 5 Feb 2009 12:32:16 +0000 Subject: [PATCH] SS: Implement basic new functionality in screensaver coordinator (tested on Mac only so far) svn path=/trunk/boinc/; revision=17146 --- checkin_notes | 14 ++ client/check_security.cpp | 10 +- client/file_names.h | 6 - clientscr/Mac_Saver_Module.h | 2 + clientscr/screensaver.cpp | 391 +++++++++++++++++++++++++---------- clientscr/screensaver.h | 14 +- clientscr/screensaver_win.h | 4 +- lib/common_defs.h | 6 + 8 files changed, 320 insertions(+), 127 deletions(-) diff --git a/checkin_notes b/checkin_notes index f49503e72a..ea157c5d6d 100644 --- a/checkin_notes +++ b/checkin_notes @@ -1139,3 +1139,17 @@ Rom 5 Feb 2008 AccountManagerInfoPage.cpp ProjectInfoPage.cpp, .h ProjectListCtrl.cpp, .h + +Charlie Feb 5 2009 + -SS: Implement basic new functionality in screensaver coordinator. + - Note: this is tested on Mac only at this point. + + client/ + check_security.cpp + file_names.h + clientscr/ + screensaver.cpp, .h + Mac_Saver_Module.h + screensaver_win.h + lib/ + common_defs.h diff --git a/client/check_security.cpp b/client/check_security.cpp index edd3247972..c3503bffef 100644 --- a/client/check_security.cpp +++ b/client/check_security.cpp @@ -344,7 +344,7 @@ int use_sandbox, int isManager return retval; } - strlcpy(full_path, dir_path, sizeof(dir_path)); + strlcpy(full_path, dir_path, sizeof(full_path)); strlcat(full_path, "/", sizeof(full_path)); strlcat(full_path, SLOTS_DIR, sizeof(full_path)); retval = stat(full_path, &sbuf); @@ -387,7 +387,7 @@ int use_sandbox, int isManager } if (use_sandbox) { - strlcpy(full_path, dir_path, sizeof(dir_path)); + strlcpy(full_path, dir_path, sizeof(full_path)); strlcat(full_path, "/", sizeof(full_path)); strlcat(full_path, SWITCHER_DIR, sizeof(full_path)); retval = stat(full_path, &sbuf); @@ -418,7 +418,7 @@ int use_sandbox, int isManager if ((sbuf.st_mode & 07777) != 04050) return -1040; - strlcpy(full_path, dir_path, sizeof(dir_path)); + strlcpy(full_path, dir_path, sizeof(full_path)); strlcat(full_path, "/", sizeof(full_path)); strlcat(full_path, SWITCHER_DIR, sizeof(full_path)); @@ -456,7 +456,7 @@ int use_sandbox, int isManager #endif #endif // __APPLE__ - strlcpy(full_path, dir_path, sizeof(dir_path)); + strlcpy(full_path, dir_path, sizeof(full_path)); strlcat(full_path, "/", sizeof(full_path)); strlcat(full_path, SS_CONFIG_FILE, sizeof(full_path)); @@ -472,7 +472,7 @@ int use_sandbox, int isManager return -1053; } // Screensaver config file ss_config.xml exists - strlcpy(full_path, dir_path, sizeof(dir_path)); + strlcpy(full_path, dir_path, sizeof(full_path)); strlcat(full_path, "/", sizeof(full_path)); strlcat(full_path, DEFAULT_SS_EXECUTABLE, sizeof(full_path)); diff --git a/client/file_names.h b/client/file_names.h index 066d401514..6a8a885497 100644 --- a/client/file_names.h +++ b/client/file_names.h @@ -90,10 +90,4 @@ extern void send_log_after(const char* filename, double t, MIOFILE& mf); #define CA_BUNDLE_FILENAME "ca-bundle.crt" #define CLIENT_AUTH_FILENAME "client_auth.xml" #define CERTIFICATE_DIRECTORY "certificates" -#define SS_CONFIG_FILE "ss_config.xml" -#ifdef _WIN32 -#define DEFAULT_SS_EXECUTABLE "boincscr.exe" -#else -#define DEFAULT_SS_EXECUTABLE "boincscr" -#endif #endif diff --git a/clientscr/Mac_Saver_Module.h b/clientscr/Mac_Saver_Module.h index 41e8ca429c..c8ef7c0abe 100644 --- a/clientscr/Mac_Saver_Module.h +++ b/clientscr/Mac_Saver_Module.h @@ -97,8 +97,10 @@ protected: static void* DataManagementProcStub( void* param ); int terminate_screensaver(int& graphics_application, RESULT *worker_app); int launch_screensaver(RESULT* rp, int& graphics_application); + int launch_default_screensaver(char *dir_path, int& graphics_application); void HandleRPCError(void); OSErr KillScreenSaver(void); + void GetDisplayPeriods(double& default_period, double& science_period, double& change_period); pthread_t m_hDataManagementThread; pid_t m_hGraphicsApplication; diff --git a/clientscr/screensaver.cpp b/clientscr/screensaver.cpp index 545db66a51..43ec2b16c8 100644 --- a/clientscr/screensaver.cpp +++ b/clientscr/screensaver.cpp @@ -33,6 +33,9 @@ #include "diagnostics.h" #include "common_defs.h" #include "util.h" +#include "common_defs.h" +#include "filesys.h" + #ifdef _WIN32 #include "gui_rpc_client.h" @@ -297,6 +300,43 @@ int CScreensaver::terminate_screensaver(int& graphics_application, RESULT *worke } +// Launch the graphics application +// +#ifdef _WIN32 +int CScreensaver::launch_default_screensaver(char *dir_path, HANDLE& graphics_application) +#else +int CScreensaver::launch_default_screensaver(char *dir_path, int& graphics_application) +#endif +{ + int retval = 0; + char full_path[1024]; + + strlcpy(full_path, dir_path, sizeof(full_path)); + strlcat(full_path, "/", sizeof(full_path)); + strlcat(full_path, DEFAULT_SS_EXECUTABLE, sizeof(full_path)); + + // For unknown reasons, the graphics application exits with + // "RegisterProcess failed (error = -50)" unless we pass its + // full path twice in the argument list to execv on Macs. + + char* argv[3]; + argv[0] = full_path; // not used + argv[1] = "--fullscreen"; + argv[2] = 0; + retval = run_program( + dir_path, + full_path, + 2, + argv, + 0, + graphics_application + ); + + BOINCTRACE(_T("launch_default_screensaver %s returned %d\n"), full_path, retval); + return retval; +} + + #ifdef _WIN32 DWORD WINAPI CScreensaver::DataManagementProc() { #else @@ -311,9 +351,19 @@ void *CScreensaver::DataManagementProc() { RESULT* previous_result_ptr = NULL; int iResultCount = 0; int iIndex = 0; - double launch_time = 0.0; + double default_phase_start_time = 0.0; + double science_phase_start_time = 0.0; double last_change_time = 0.0; - double last_run_check_time = 0.0; + double gfx_default_period = GFX_DEFAULT_PERIOD; + double gfx_science_period = GFX_SCIENCE_PERIOD; + double gfx_change_period = GFX_CHANGE_PERIOD; + + SS_PHASE ss_phase = DEFAULT_SS_PHASE; + bool default_ss_exists = false; + bool science_gfx_running = false; + bool default_gfx_running = false; + bool switch_to_default_gfx = false; + char full_path[1024]; #ifdef _WIN32 BOINCTRACE(_T("CScreensaver::DataManagementProc - Display screen saver loading message\n")); @@ -323,7 +373,31 @@ void *CScreensaver::DataManagementProc() { // Set the starting point for iterating through the results m_iLastResultShown = 0; m_tLastResultChangeTime = 0; -#endif +#endif + +#ifdef __APPLE__ + char * default_ss_dir_path = "/Library/Application Support/BOINC Data"; +#else + // TODO: Obtain correct path to Windows default OpenGL screensaver executable + char * default_ss_dir_path = "C:\Program Files\BOINC"; +#endif + strlcpy(full_path, default_ss_dir_path, sizeof(full_path)); + strlcat(full_path, "/", sizeof(full_path)); + strlcat(full_path, DEFAULT_SS_EXECUTABLE, sizeof(full_path)); + + if (boinc_file_exists(full_path)) { + default_ss_exists = true; + ss_phase = DEFAULT_SS_PHASE; + default_phase_start_time = dtime(); + science_phase_start_time = 0; + switch_to_default_gfx = true; + } else { + ss_phase = SCIENCE_SS_PHASE; + default_phase_start_time = 0; + science_phase_start_time = dtime(); + } + + GetDisplayPeriods(gfx_default_period, gfx_science_period, gfx_change_period); while (true) { for (int i = 0; i < 4; i++) { @@ -399,138 +473,227 @@ void *CScreensaver::DataManagementProc() { continue; } - // Core client suspended? - if (suspend_reason && !(suspend_reason & SUSPEND_REASON_CPU_USAGE_LIMIT)) { - SetError(TRUE, SCRAPPERR_BOINCSUSPENDED); - if (m_hGraphicsApplication || previous_result_ptr) { - // use previous_result_ptr because graphics_app_result_ptr may no longer be valid - terminate_screensaver(m_hGraphicsApplication, previous_result_ptr); - if (m_hGraphicsApplication == 0) { - graphics_app_result_ptr = NULL; - } else { - // waitpid test will clear m_hGraphicsApplication and graphics_app_result_ptr - } - previous_result_ptr = NULL; + // Time to switch to default graphics? + if (default_ss_exists && (ss_phase == SCIENCE_SS_PHASE)) { + if (science_phase_start_time && ((dtime() - science_phase_start_time) > gfx_science_period)) { + switch_to_default_gfx = true; + ss_phase = DEFAULT_SS_PHASE; + default_phase_start_time = dtime(); + science_phase_start_time = 0; } - continue; } - -#if SIMULATE_NO_GRAPHICS /* FOR TESTING */ - - SetError(TRUE, SCRAPPERR_BOINCNOGRAPHICSAPPSEXECUTING); - -#else /* NORMAL OPERATION */ - - // Is the current graphics app's associated task still running? - if ((m_hGraphicsApplication) || (graphics_app_result_ptr)) { - - iResultCount = results.results.size(); - graphics_app_result_ptr = NULL; - - // Find the current task in the new results vector (if it still exists) - for (iIndex = 0; iIndex < iResultCount; iIndex++) { - theResult = results.results.at(iIndex); - - if (is_same_task(theResult, previous_result_ptr)) { - graphics_app_result_ptr = theResult; - previous_result = *theResult; - previous_result_ptr = &previous_result; - break; - } - } - - // V6 graphics only: if worker application has stopped running, terminate_screensaver - if ((graphics_app_result_ptr == NULL) && (m_hGraphicsApplication != 0)) { - if (previous_result_ptr) { - BOINCTRACE(_T("CScreensaver::DataManagementProc - %s finished\n"), - previous_result.graphics_exec_path.c_str()); - } - terminate_screensaver(m_hGraphicsApplication, previous_result_ptr); - previous_result_ptr = NULL; - // waitpid test will clear m_hGraphicsApplication - } - - if (last_change_time && ((dtime() - last_change_time) > GFX_CHANGE_PERIOD)) { - if (count_active_graphic_apps(results, previous_result_ptr) > 0) { - if (previous_result_ptr) { - BOINCTRACE(_T("CScreensaver::DataManagementProc - time to change: %s / %s\n"), - previous_result.name.c_str(), previous_result.graphics_exec_path.c_str()); - } - terminate_screensaver(m_hGraphicsApplication, graphics_app_result_ptr); + + if (switch_to_default_gfx) { + if (science_gfx_running) { + if (m_hGraphicsApplication || previous_result_ptr) { + // use previous_result_ptr because graphics_app_result_ptr may no longer be valid + terminate_screensaver(m_hGraphicsApplication, previous_result_ptr); if (m_hGraphicsApplication == 0) { graphics_app_result_ptr = NULL; - // Save previous_result and previous_result_ptr for get_random_graphics_app() call + science_gfx_running = false; } else { // waitpid test will clear m_hGraphicsApplication and graphics_app_result_ptr } + previous_result_ptr = NULL; + } + } else { + if (default_ss_exists && !default_gfx_running) { + switch_to_default_gfx = false; + retval = launch_default_screensaver(default_ss_dir_path, m_hGraphicsApplication); + if (retval) { + m_hGraphicsApplication = 0; + previous_result_ptr = NULL; + graphics_app_result_ptr = NULL; + default_gfx_running = false; + } else { + default_gfx_running = true; + } } - last_change_time = dtime(); } } + + // Core client suspended? + if (suspend_reason && !(suspend_reason & SUSPEND_REASON_CPU_USAGE_LIMIT)) { + SetError(TRUE, SCRAPPERR_BOINCSUSPENDED); + if (default_ss_exists && !default_gfx_running) { + switch_to_default_gfx = true; + } + } else { + // Time to switch to science graphics? + if (ss_phase == DEFAULT_SS_PHASE) { + if (default_phase_start_time && ((dtime() - default_phase_start_time) > gfx_default_period)) { + ss_phase = SCIENCE_SS_PHASE; + default_phase_start_time = 0; + science_phase_start_time = dtime(); + } + } + } + + if (ss_phase == SCIENCE_SS_PHASE) { + +#if SIMULATE_NO_GRAPHICS /* FOR TESTING */ + + SetError(TRUE, SCRAPPERR_BOINCNOGRAPHICSAPPSEXECUTING); + if (default_ss_exists && !default_gfx_running) { + switch_to_default_gfx = true; + } + +#else /* NORMAL OPERATION */ + + if (science_gfx_running) { + // Is the current graphics app's associated task still running? - // If no current graphics app, pick an active task at random and launch its graphics app - if ((m_hGraphicsApplication == 0) && (graphics_app_result_ptr == NULL)) { - graphics_app_result_ptr = get_random_graphics_app(results, previous_result_ptr); - previous_result_ptr = NULL; - - if (graphics_app_result_ptr) { - retval = launch_screensaver(graphics_app_result_ptr, m_hGraphicsApplication); + if ((m_hGraphicsApplication) || (graphics_app_result_ptr)) { + iResultCount = results.results.size(); + graphics_app_result_ptr = NULL; + + // Find the current task in the new results vector (if it still exists) + for (iIndex = 0; iIndex < iResultCount; iIndex++) { + theResult = results.results.at(iIndex); + + if (is_same_task(theResult, previous_result_ptr)) { + graphics_app_result_ptr = theResult; + previous_result = *theResult; + previous_result_ptr = &previous_result; + break; + } + } + + // V6 graphics only: if worker application has stopped running, terminate_screensaver + if ((graphics_app_result_ptr == NULL) && (m_hGraphicsApplication != 0)) { + if (previous_result_ptr) { + BOINCTRACE(_T("CScreensaver::DataManagementProc - %s finished\n"), + previous_result.graphics_exec_path.c_str()); + } + terminate_screensaver(m_hGraphicsApplication, previous_result_ptr); + previous_result_ptr = NULL; + // waitpid test will clear m_hGraphicsApplication + } + + if (last_change_time && ((dtime() - last_change_time) > gfx_change_period)) { + if (count_active_graphic_apps(results, previous_result_ptr) > 0) { + if (previous_result_ptr) { + BOINCTRACE(_T("CScreensaver::DataManagementProc - time to change: %s / %s\n"), + previous_result.name.c_str(), previous_result.graphics_exec_path.c_str()); + } + terminate_screensaver(m_hGraphicsApplication, graphics_app_result_ptr); + if (m_hGraphicsApplication == 0) { + graphics_app_result_ptr = NULL; + science_gfx_running = false; + // Save previous_result and previous_result_ptr for get_random_graphics_app() call + } else { + // waitpid test will clear m_hGraphicsApplication and graphics_app_result_ptr + } + } + last_change_time = dtime(); + } + } + } // End if (science_gfx_running) + + // If no current graphics app, pick an active task at random and launch its graphics app + if ((default_gfx_running || (m_hGraphicsApplication == 0)) && (graphics_app_result_ptr == NULL)) { + graphics_app_result_ptr = get_random_graphics_app(results, previous_result_ptr); + previous_result_ptr = NULL; + + if (graphics_app_result_ptr) { + if (default_gfx_running) { + kill_program(m_hGraphicsApplication); + // waitpid test will clear m_hGraphicsApplication and graphics_app_result_ptr + } else { + retval = launch_screensaver(graphics_app_result_ptr, m_hGraphicsApplication); + if (retval) { + m_hGraphicsApplication = 0; + previous_result_ptr = NULL; + graphics_app_result_ptr = NULL; + science_gfx_running = false; + } else { + #ifdef __APPLE__ + // Show ScreenSaverAppStartingMsg for GFX_STARTING_MSG_DURATION seconds + SetError(FALSE, SCRAPPERR_BOINCAPPFOUNDGRAPHICSLOADING); + #endif + SetError(FALSE, SCRAPPERR_SCREENSAVERRUNNING); + last_change_time = dtime(); + science_gfx_running = true; + // Make a local copy of current result, since original pointer + // may have been freed by the time we perform later tests + previous_result = *graphics_app_result_ptr; + previous_result_ptr = &previous_result; + if (previous_result_ptr) { + BOINCTRACE(_T("CScreensaver::DataManagementProc - launching %s\n"), + previous_result.graphics_exec_path.c_str()); + } + } + } + } else { + // No science graphics available + if (state.projects.size() == 0) { + // We are not attached to any projects + SetError(TRUE, SCRAPPERR_BOINCNOPROJECTSDETECTED); + } else if (results.results.size() == 0) { + // We currently do not have any applications to run + SetError(TRUE, SCRAPPERR_BOINCNOAPPSEXECUTING); + } else { + // We currently do not have any graphics capable application + if (m_bV5_GFX_app_is_running) { + SetError(TRUE, SCRAPPERR_DAEMONALLOWSNOGRAPHICS); + } else { + SetError(TRUE, SCRAPPERR_BOINCNOGRAPHICSAPPSEXECUTING); + } + } + + // We can't run a science graphics app, so run the default graphics if available + if (default_ss_exists && !default_gfx_running) { + switch_to_default_gfx = true; + } + + + + } // End if no science graphics available + } // End if no current science graphics app is running + +#endif // ! SIMULATE_NO_GRAPHICS + + if (switch_to_default_gfx) { + switch_to_default_gfx = false; + retval = launch_default_screensaver(default_ss_dir_path, m_hGraphicsApplication); if (retval) { m_hGraphicsApplication = 0; previous_result_ptr = NULL; graphics_app_result_ptr = NULL; + default_gfx_running = false; } else { -#ifdef __APPLE__ - // Show ScreenSaverAppStartingMsg for GFX_STARTING_MSG_DURATION seconds - SetError(FALSE, SCRAPPERR_BOINCAPPFOUNDGRAPHICSLOADING); -#endif - SetError(FALSE, SCRAPPERR_SCREENSAVERRUNNING); - launch_time = dtime(); - last_change_time = launch_time; - last_run_check_time = launch_time; - // Make a local copy of current result, since original pointer - // may have been freed by the time we perform later tests - previous_result = *graphics_app_result_ptr; - previous_result_ptr = &previous_result; - if (previous_result_ptr) { - BOINCTRACE(_T("CScreensaver::DataManagementProc - launching %s\n"), - previous_result.graphics_exec_path.c_str()); - } - } - } else { - if (state.projects.size() == 0) { - // We are not attached to any projects - SetError(TRUE, SCRAPPERR_BOINCNOPROJECTSDETECTED); - } else if (results.results.size() == 0) { - // We currently do not have any applications to run - SetError(TRUE, SCRAPPERR_BOINCNOAPPSEXECUTING); - } else { - // We currently do not have any graphics capable application - if (m_bV5_GFX_app_is_running) { - SetError(TRUE, SCRAPPERR_DAEMONALLOWSNOGRAPHICS); - } else { - SetError(TRUE, SCRAPPERR_BOINCNOGRAPHICSAPPSEXECUTING); - } + default_gfx_running = true; } } - } else { // End if ((m_hGraphicsApplication == 0) && (graphics_app_result_ptr == NULL)) - - // Is the graphics app still running? - if (m_hGraphicsApplication) { - if (!process_exists(m_hGraphicsApplication)) { - // Something has happened to the previously selected screensaver - // application. Start a different one. - BOINCTRACE(_T("CScreensaver::DataManagementProc - Graphics application isn't running, start a new one.\n")); - m_hGraphicsApplication = 0; - graphics_app_result_ptr = NULL; - continue; - } else { + } // End if (ss_phase == SCIENCE_SS_PHASE) + + + + // Is the graphics app still running? + if (m_hGraphicsApplication) { + if (!process_exists(m_hGraphicsApplication)) { + // Something has happened to the previously selected screensaver + // application. Start a different one. + BOINCTRACE(_T("CScreensaver::DataManagementProc - Graphics application isn't running, start a new one.\n")); + m_hGraphicsApplication = 0; + graphics_app_result_ptr = NULL; + default_gfx_running = false; + science_gfx_running = false; + continue; + } else { #ifdef _WIN32 - CheckForegroundWindow(); + CheckForegroundWindow(); #endif - } } } -#endif // ! SIMULATE_NO_GRAPHICS + } // end while(true) } + + +void CScreensaver::GetDisplayPeriods(double& default_period, + double& science_period, + double& change_period) { + +// TODO: pares ss_config.xml file here. +} \ No newline at end of file diff --git a/clientscr/screensaver.h b/clientscr/screensaver.h index e7a70524fb..a50732a32e 100644 --- a/clientscr/screensaver.h +++ b/clientscr/screensaver.h @@ -19,9 +19,21 @@ #ifndef __SCREENSAVER_H__ #define __SCREENSAVER_H__ - +// Default values, overriden by screensaver config file ss_config.xml +#if 0 +define GFX_DEFAULT_PERIOD 600 /* if default OpenGL screensaver exists, display it for 600 secs */ +#define GFX_SCIENCE_PERIOD 1800 /* Display various science graphics apps for 1800 secs */ #define GFX_CHANGE_PERIOD 600 /* if > 1 CPUs, change screensaver every 600 secs */ +#else // Temporary for testing +#define GFX_DEFAULT_PERIOD 15 /* if default OpenGL screensaver exists, display it for 15 secs */ +#define GFX_SCIENCE_PERIOD 30 /* Display various science graphics apps for 30 secs */ +#define GFX_CHANGE_PERIOD 15 /* if > 1 CPUs, change screensaver every q5 secs */ +#endif +enum SS_PHASE { + DEFAULT_SS_PHASE, + SCIENCE_SS_PHASE +}; //----------------------------------------------------------------------------- // Error / status codes diff --git a/clientscr/screensaver_win.h b/clientscr/screensaver_win.h index ab60dee890..4067639cbe 100644 --- a/clientscr/screensaver_win.h +++ b/clientscr/screensaver_win.h @@ -160,8 +160,10 @@ protected: int terminate_screensaver(HANDLE& graphics_application, RESULT *worker_app); int launch_screensaver(RESULT* rp, HANDLE& graphics_application); + int launch_default_screensaver(char *dir_path, HANDLE& graphics_application); void HandleRPCError(void); - + void GetDisplayPeriods(double& default_period, double& science_period, double& change_period); + // Determine if two RESULT pointers refer to the same task bool is_same_task(RESULT* taska, RESULT* taskb); diff --git a/lib/common_defs.h b/lib/common_defs.h index 33102d3851..b836c31624 100644 --- a/lib/common_defs.h +++ b/lib/common_defs.h @@ -195,6 +195,12 @@ struct VERSION_INFO { #define GRAPHICS_APP_FILENAME "graphics_app" #define ASSIGNED_WU_STR "asgn" #define GUI_RPC_PASSWD_FILE "gui_rpc_auth.cfg" +#define SS_CONFIG_FILE "ss_config.xml" +#ifdef _WIN32 +#define DEFAULT_SS_EXECUTABLE "boincscr.exe" +#else +#define DEFAULT_SS_EXECUTABLE "boincscr" +#endif #endif