// Delete the file located at path. // If "retry" is set, do retries for 5 sec in case some // other program (e.g. virus checker) has the file locked. // Don't do this if deleting directories - it can lock up the Manager. // int delete_project_owned_file(const char* path, bool retry) { int retval = 0; retval = delete_project_owned_file_aux(path); if (retval && retry) { if (log_flags.slot_debug) { msg_printf(0, MSG_INFO, "[slot] delete of %s failed (%d); retrying", path, retval ); } double start = dtime(); do { boinc_sleep(drand()*2); // avoid lockstep retval = delete_project_owned_file_aux(path); if (!retval) break; } while (dtime() < start + FILE_RETRY_INTERVAL); } if (retval) { if (log_flags.slot_debug) { msg_printf(0, MSG_INFO, "[slot] failed to remove file %s: %s", path, boincerror(retval) ); } safe_strcpy(boinc_failed_file, path); return ERR_UNLINK; } if (log_flags.slot_debug) { msg_printf(0, MSG_INFO, "[slot] removed file %s", path); } return 0; }
// Quit operations static void quit_client() { gstate.requested_exit = true; while (1) { boinc_sleep(1.0); if (gstate.cleanup_completed) break; } }
void CBOINCBaseFrame::ShowNotCurrentlyConnectedAlert() { CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced(); CMainDocument* pDoc = wxGetApp().GetDocument(); wxString strConnectedCompter = wxEmptyString; wxString strDialogTitle = wxEmptyString; wxString strDialogMessage = wxEmptyString; wxASSERT(pSkinAdvanced); wxASSERT(wxDynamicCast(pSkinAdvanced, CSkinAdvanced)); wxASSERT(pDoc); wxASSERT(wxDynamicCast(pDoc, CMainDocument)); wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::ShowNotCurrentlyConnectedAlert - Function Begin")); // Did BOINC crash on local computer? If so restart it and reconnect. pDoc->GetConnectedComputerName(strConnectedCompter); if (pDoc->IsComputerNameLocal(strConnectedCompter)) { if (pDoc->m_pClientManager->AutoRestart()) { boinc_sleep(0.5); // Allow time for Client to restart if (pDoc->m_pClientManager->IsBOINCCoreRunning()) { pDoc->Reconnect(); return; } } else { // Don't ask whether to reconnect to local client if it is not running if (!pDoc->m_pClientManager->IsBOINCCoreRunning()) { return; } } } // %s is the application name // i.e. 'BOINC Manager', 'GridRepublic Manager' strDialogTitle.Printf( _("%s - Connection Status"), pSkinAdvanced->GetApplicationName().c_str() ); // 1st %s is the application name // i.e. 'BOINC Manager', 'GridRepublic Manager' // 2nd %s is the project name // i.e. 'BOINC', 'GridRepublic' // 3nd %s is the project name // i.e. 'BOINC', 'GridRepublic' strDialogMessage.Printf( _("%s is not currently connected to a %s client.\nPlease use the 'Advanced\\Select Computer...' menu option to connect up to a %s client.\nTo connect up to your local computer please use 'localhost' as the host name."), pSkinAdvanced->GetApplicationName().c_str(), pSkinAdvanced->GetApplicationShortName().c_str(), pSkinAdvanced->GetApplicationShortName().c_str() ); ShowAlert( strDialogTitle, strDialogMessage, wxOK | wxICON_ERROR ); wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::ShowNotCurrentlyConnectedAlert - Function End")); }
// Terminate any screensaver graphics application // int CScreensaver::terminate_v6_screensaver(GFXAPP_ID& graphics_application) { int retval = 0; #ifdef __APPLE__ // Under sandbox security, use gfx_switcher to kill default gfx app // as user boinc_master and group boinc_master. The man page for // kill() says the user ID of the process sending the signal must // match that of the target process, though in practice that seems // not to be true on the Mac. char current_dir[PATH_MAX]; char gfx_pid[16]; pid_t thePID; int i; sprintf(gfx_pid, "%d", graphics_application); getcwd( current_dir, sizeof(current_dir)); char* argv[4]; argv[0] = "gfx_switcher"; argv[1] = "-kill_gfx"; argv[2] = gfx_pid; argv[3] = 0; retval = run_program( current_dir, m_gfx_Switcher_Path, 3, argv, 0, thePID ); for (i=0; i<200; i++) { boinc_sleep(0.01); // Wait 2 seconds max // Prevent gfx_switcher from becoming a zombie if (waitpid(thePID, 0, WNOHANG) == thePID) { break; } } #endif #ifdef _WIN32 HWND hBOINCGraphicsWindow = FindWindow(BOINC_WINDOW_CLASS_NAME, NULL); if (hBOINCGraphicsWindow) { CloseWindow(hBOINCGraphicsWindow); Sleep(1000); hBOINCGraphicsWindow = FindWindow(BOINC_WINDOW_CLASS_NAME, NULL); if (hBOINCGraphicsWindow) { kill_program(graphics_application); } } #endif // For safety, call kill_program even under Apple sandbox security kill_program(graphics_application); return retval; }
int boinc_main_loop() { int retval; retval = initialize(); if (retval) return retval; #ifdef __APPLE__ // If we run too soon during system boot we can cause a kernel panic if (gstate.executing_as_daemon) { if (TickCount() < (120*60)) { // If system has been up for less than 2 minutes boinc_sleep(30.); } } #endif retval = gstate.init(); if (retval) { log_message_error("gstate.init() failed", retval); return retval; } log_message_startup("Initialization completed"); while (1) { if (!gstate.poll_slow_events()) { gstate.do_io_or_sleep(POLL_INTERVAL); } fflush(stderr); fflush(stdout); if (gstate.time_to_exit()) { msg_printf(NULL, MSG_INFO, "Time to exit"); break; } if (gstate.requested_exit) { if (cc_config.abort_jobs_on_exit) { if (!gstate.in_abort_sequence) { msg_printf(NULL, MSG_INFO, "Exit requested; starting abort sequence" ); gstate.start_abort_sequence(); } } else { msg_printf(NULL, MSG_INFO, "Exiting"); break; } } if (gstate.in_abort_sequence) { if (gstate.abort_sequence_done()) { msg_printf(NULL, MSG_INFO, "Abort sequence done; exiting"); break; } } } return finalize(); }
void benchmark_wait_to_start(int which) { while (1) { if (boinc_file_exists(file_names[which])) { break; } #ifndef _WIN32 // UNIX: check if client has died. // Not needed on windows, where we run as thread in client process // if (getppid() == 1) { exit(0); } #endif boinc_sleep(0.1); } }
bool CScreensaver::DestroyDataManagementThread() { m_bQuitDataManagementProc = true; // Tell DataManagementProc thread to exit if (!m_hDataManagementThread) return true; 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); } if (rpc) { 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; }
/// Delete the file located at path. /// If "retry" is set, do retries for 5 sec in case some /// other program (e.g. virus checker) has the file locked. /// Don't do this if deleting directories - it can lock up the Manager. /// /// \param[in] path The path name of the file that should be deleted. /// \param[in] retry If true this function will try to delete the file /// multiple times if the first attempt failed. /// \return Zero on success, ERR_UNLINK on error. int delete_project_owned_file(const char* path, bool retry) { int retval = 0; if (!boinc_file_or_symlink_exists(path)) { return 0; } retval = delete_project_owned_file_aux(path); if (retval && retry) { double start = dtime(); do { boinc_sleep(drand() * 2.0); // avoid lockstep retval = delete_project_owned_file_aux(path); if (!retval) break; } while (dtime() < start + FILE_RETRY_INTERVAL); } if (retval) { safe_strcpy(boinc_failed_file, path); return ERR_UNLINK; } return 0; }
void CMainDocument::KillRPCThread() { wxMutexError mutexErr = wxMUTEX_NO_ERROR; int i; if (!m_RPCThread) { return; } m_bNeedRefresh = false; m_bNeedTaskBarRefresh = false; rpcClient.close(); // Abort any async RPC in progress (in case hung) // On some platforms, Delete() takes effect only when thread calls TestDestroy() // Wait for thread to unlock mutex with m_pRPC_Thread_Condition->Wait() mutexErr = m_pRPC_Thread_Mutex->Lock(); // Blocks until thread unlocks the mutex wxASSERT(mutexErr == wxMUTEX_NO_ERROR); m_bShutDownRPCThread = true; m_pRPC_Thread_Condition->Signal(); // Unblock the thread mutexErr = m_pRPC_Thread_Mutex->Unlock(); // Release the mutex so thread can lock it wxASSERT(mutexErr == wxMUTEX_NO_ERROR); RPC_requests.clear(); current_rpc_request.clear(); // Wait up to RPC_KILL_DELAY milliseconds for thread to exit on its own for (i=0; i< RPC_KILL_DELAY; ++i) { boinc_sleep(.001); // Defer to RPC thread for 1 millisecond if (!m_RPCThread) { return; // RPC thread sets m_RPCThread to NULL when it exits } } // Thread failed to exit, so forcefully kill it m_RPCThread->Kill(); }
// Delete the file located at path. // If "retry" is set, do retries for 5 sec in case some // other program (e.g. virus checker) has the file locked. // Don't do this if deleting directories - it can lock up the Manager. // int delete_project_owned_file(const char* path, bool retry) { int retval = 0; if (!boinc_file_or_symlink_exists(path)) { return 0; } retval = delete_project_owned_file_aux(path); if (retval && retry) { double start = dtime(); do { boinc_sleep(drand()*2); // avoid lockstep retval = delete_project_owned_file_aux(path); if (!retval) break; } while (dtime() < start + FILE_RETRY_INTERVAL); } if (retval) { safe_strcpy(boinc_failed_file, path); return ERR_UNLINK; } if (log_flags.slot_debug) { msg_printf(0, MSG_INFO, "[slot] removed file %s", path); } return 0; }
DataMgmtProcType CScreensaver::DataManagementProc() { int retval = 0; int suspend_reason = 0; RESULT* theResult = NULL; RESULT* graphics_app_result_ptr = NULL; RESULT previous_result; // previous_result_ptr = &previous_result when previous_result is valid, else NULL RESULT* previous_result_ptr = NULL; int iResultCount = 0; int iIndex = 0; double default_phase_start_time = 0.0; double science_phase_start_time = 0.0; double last_change_time = 0.0; // If we run default screensaver during science phase because no science graphics // are available, then shorten next default graphics phase by that much time. double default_saver_start_time_in_science_phase = 0.0; double default_saver_duration_in_science_phase = 0.0; SS_PHASE ss_phase = DEFAULT_SS_PHASE; bool switch_to_default_gfx = false; bool killing_default_gfx = false; int exit_status = 0; char* default_ss_dir_path = NULL; char full_path[1024]; BOINCTRACE(_T("CScreensaver::DataManagementProc - Display screen saver loading message\n")); SetError(TRUE, SCRAPPERR_BOINCSCREENSAVERLOADING); // No GFX App is running: show moving BOINC logo #ifdef _WIN32 m_tThreadCreateTime = time(0); // Set the starting point for iterating through the results m_iLastResultShown = 0; m_tLastResultChangeTime = 0; #endif m_bDefault_ss_exists = false; m_bScience_gfx_running = false; m_bDefault_gfx_running = false; m_bShow_default_ss_first = false; #ifdef __APPLE__ m_vIncompatibleGfxApps.clear(); default_ss_dir_path = "/Library/Application Support/BOINC Data"; #else default_ss_dir_path = (char*)m_strBOINCInstallDirectory.c_str(); #endif strlcpy(full_path, default_ss_dir_path, sizeof(full_path)); strlcat(full_path, PATH_SEPARATOR, sizeof(full_path)); strlcat(full_path, THE_DEFAULT_SS_EXECUTABLE, sizeof(full_path)); if (boinc_file_exists(full_path)) { m_bDefault_ss_exists = true; } else { SetError(TRUE, SCRAPPERR_CANTLAUNCHDEFAULTGFXAPP); // No GFX App is running: show moving BOINC logo } if (m_bDefault_ss_exists && m_bShow_default_ss_first) { 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(); } while (true) { for (int i = 0; i < 4; i++) { // *** // *** Things that should be run frequently. // *** 4 times per second. // *** // Are we supposed to exit the screensaver? if (m_bQuitDataManagementProc) { // If main thread has requested we exit BOINCTRACE(_T("CScreensaver::DataManagementProc - Thread told to stop\n")); if (m_hGraphicsApplication || graphics_app_result_ptr) { if (m_bDefault_gfx_running) { BOINCTRACE(_T("CScreensaver::DataManagementProc - Terminating default screensaver\n")); terminate_default_screensaver(m_hGraphicsApplication); } else { BOINCTRACE(_T("CScreensaver::DataManagementProc - Terminating screensaver\n")); terminate_screensaver(m_hGraphicsApplication, graphics_app_result_ptr); } graphics_app_result_ptr = NULL; previous_result_ptr = NULL; m_hGraphicsApplication = 0; } BOINCTRACE(_T("CScreensaver::DataManagementProc - Stopping...\n")); m_bDataManagementProcStopped = true; // Tell main thread that we exited return 0; // Exit the thread } boinc_sleep(0.25); } // *** // *** Things that should be run less frequently. // *** 1 time per second. // *** // Blank screen saver? if ((m_dwBlankScreen) && (time(0) > m_dwBlankTime) && (m_dwBlankTime > 0)) { BOINCTRACE(_T("CScreensaver::DataManagementProc - Time to blank\n")); SetError(FALSE, SCRAPPERR_SCREENSAVERBLANKED); // Blanked - hide moving BOINC logo m_bQuitDataManagementProc = true; continue; // Code above will exit the thread } BOINCTRACE(_T("CScreensaver::DataManagementProc - ErrorMode = '%d', ErrorCode = '%x'\n"), m_bErrorMode, m_hrError); if (!m_bConnected) { HandleRPCError(); } if (m_bConnected) { // Do we need to get the core client state? if (m_bResetCoreState) { // Try and get the current state of the CC retval = rpc->get_state(state); if (retval) { // CC may not yet be running HandleRPCError(); continue; } else { m_bResetCoreState = false; } } // Update our task list retval = rpc->get_screensaver_tasks(suspend_reason, results); if (retval) { // rpc call returned error HandleRPCError(); m_bResetCoreState = true; continue; } } else { results.clear(); } // Time to switch to default graphics phase? if (m_bDefault_ss_exists && (ss_phase == SCIENCE_SS_PHASE) && (m_fGFXDefaultPeriod > 0)) { if (science_phase_start_time && ((dtime() - science_phase_start_time) > m_fGFXSciencePeriod)) { if (!m_bDefault_gfx_running) { switch_to_default_gfx = true; } ss_phase = DEFAULT_SS_PHASE; default_phase_start_time = dtime(); science_phase_start_time = 0; if (m_bDefault_gfx_running && default_saver_start_time_in_science_phase) { // Remember how long default graphics ran during science phase default_saver_duration_in_science_phase += (dtime() - default_saver_start_time_in_science_phase); } default_saver_start_time_in_science_phase = 0; } } // Time to switch to science graphics phase? if ((ss_phase == DEFAULT_SS_PHASE) && m_bConnected && (m_fGFXSciencePeriod > 0)) { if (default_phase_start_time && ((dtime() - default_phase_start_time + default_saver_duration_in_science_phase) > m_fGFXDefaultPeriod)) { // BOINCTRACE(_T("CScreensaver::Ending Default phase: now=%f, default_phase_start_time=%f, default_saver_duration_in_science_phase=%f\n"), // dtime(), default_phase_start_time, default_saver_duration_in_science_phase); ss_phase = SCIENCE_SS_PHASE; default_phase_start_time = 0; default_saver_duration_in_science_phase = 0; science_phase_start_time = dtime(); if (m_bDefault_gfx_running) { default_saver_start_time_in_science_phase = science_phase_start_time; } switch_to_default_gfx = false; } } // Core client suspended? // We ignore SUSPEND_REASON_CPU_USAGE in SS coordinator, so it won't kill graphics apps for // short-term CPU usage spikes (such as anti-virus.) Added 9 April 2010 if (suspend_reason && !(suspend_reason & (SUSPEND_REASON_CPU_THROTTLE | SUSPEND_REASON_CPU_USAGE))) { if (!m_bDefault_gfx_running) { SetError(TRUE, m_hrError); // No GFX App is running: show moving BOINC logo if (m_bDefault_ss_exists) { switch_to_default_gfx = true; } } } if (switch_to_default_gfx) { if (m_bScience_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; m_bScience_gfx_running = false; } else { // HasProcessExited() test will clear m_hGraphicsApplication and graphics_app_result_ptr } previous_result_ptr = NULL; } } else { if (!m_bDefault_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; m_bDefault_gfx_running = false; SetError(TRUE, SCRAPPERR_CANTLAUNCHDEFAULTGFXAPP); // No GFX App is running: show moving BOINC logo } else { m_bDefault_gfx_running = true; if (ss_phase == SCIENCE_SS_PHASE) { default_saver_start_time_in_science_phase = dtime(); } SetError(FALSE, SCRAPPERR_BOINCSCREENSAVERLOADING); // A GFX App is running: hide moving BOINC logo } } } } if ((ss_phase == SCIENCE_SS_PHASE) && !switch_to_default_gfx) { #if SIMULATE_NO_GRAPHICS /* FOR TESTING */ if (!m_bDefault_gfx_running) { SetError(TRUE, m_hrError); // No GFX App is running: show moving BOINC logo if (m_bDefault_ss_exists) { switch_to_default_gfx = true; } } #else /* NORMAL OPERATION */ if (m_bScience_gfx_running) { // Is the current graphics app's associated task still running? if ((m_hGraphicsApplication) || (graphics_app_result_ptr)) { iResultCount = (int)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 ); } terminate_screensaver(m_hGraphicsApplication, previous_result_ptr); previous_result_ptr = NULL; if (m_hGraphicsApplication == 0) { graphics_app_result_ptr = NULL; m_bScience_gfx_running = false; // Save previous_result and previous_result_ptr for get_random_graphics_app() call } else { // HasProcessExited() test will clear m_hGraphicsApplication and graphics_app_result_ptr } } if (last_change_time && (m_fGFXChangePeriod > 0) && ((dtime() - last_change_time) > m_fGFXChangePeriod) ) { 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, previous_result.graphics_exec_path ); } terminate_screensaver(m_hGraphicsApplication, graphics_app_result_ptr); if (m_hGraphicsApplication == 0) { graphics_app_result_ptr = NULL; m_bScience_gfx_running = false; // Save previous_result and previous_result_ptr for get_random_graphics_app() call } else { // HasProcessExited() test will clear m_hGraphicsApplication and graphics_app_result_ptr } } last_change_time = dtime(); } } } // End if (m_bScience_gfx_running) // If no current graphics app, pick an active task at random // and launch its graphics app // if ((m_bDefault_gfx_running || (m_hGraphicsApplication == 0)) && (graphics_app_result_ptr == NULL)) { if (suspend_reason && !(suspend_reason & (SUSPEND_REASON_CPU_THROTTLE | SUSPEND_REASON_CPU_USAGE))) { graphics_app_result_ptr = NULL; } else { graphics_app_result_ptr = get_random_graphics_app(results, previous_result_ptr); previous_result_ptr = NULL; } if (graphics_app_result_ptr) { if (m_bDefault_gfx_running) { terminate_default_screensaver(m_hGraphicsApplication); killing_default_gfx = true; // Remember how long default graphics ran during science phase if (default_saver_start_time_in_science_phase) { default_saver_duration_in_science_phase += (dtime() - default_saver_start_time_in_science_phase); //BOINCTRACE(_T("CScreensaver::During Science phase: now=%f, default_saver_start_time=%f, default_saver_duration=%f\n"), // dtime(), default_saver_start_time_in_science_phase, default_saver_duration_in_science_phase); } default_saver_start_time_in_science_phase = 0; // HasProcessExited() 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; m_bScience_gfx_running = false; } else { // A GFX App is running: hide moving BOINC logo // SetError(FALSE, SCRAPPERR_BOINCSCREENSAVERLOADING); last_change_time = dtime(); m_bScience_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 ); } } } } else { if (!m_bDefault_gfx_running) { // We can't run a science graphics app, so run the default graphics if available SetError(TRUE, m_hrError); if (m_bDefault_ss_exists) { 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; if (!m_bDefault_gfx_running) { retval = launch_default_screensaver(default_ss_dir_path, m_hGraphicsApplication); if (retval) { m_hGraphicsApplication = 0; previous_result_ptr = NULL; graphics_app_result_ptr = NULL; m_bDefault_gfx_running = false; SetError(TRUE, SCRAPPERR_CANTLAUNCHDEFAULTGFXAPP); // No GFX App is running: show BOINC logo } else { m_bDefault_gfx_running = true; default_saver_start_time_in_science_phase = dtime(); SetError(FALSE, SCRAPPERR_BOINCSCREENSAVERLOADING); // Default GFX App is running: hide moving BOINC logo } } } } // End if ((ss_phase == SCIENCE_SS_PHASE) && !switch_to_default_gfx) // Is the graphics app still running? if (m_hGraphicsApplication) { if (HasProcessExited(m_hGraphicsApplication, exit_status)) { // 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")); if (m_bDefault_gfx_running) { // If we were able to connect to core client // but gfx app can't, don't use it. // BOINCTRACE(_T("CScreensaver::DataManagementProc - Default graphics application exited with code %d.\n"), exit_status); if (!killing_default_gfx) { // If this is an unexpected exit if (exit_status == DEFAULT_GFX_CANT_CONNECT) { SetError(TRUE, SCRAPPERR_DEFAULTGFXAPPCANTCONNECT); // No GFX App is running: show moving BOINC logo } else { SetError(TRUE, SCRAPPERR_DEFAULTGFXAPPCRASHED); // No GFX App is running: show moving BOINC logo } m_bDefault_ss_exists = false; ss_phase = SCIENCE_SS_PHASE; } killing_default_gfx = false; } SetError(TRUE, SCRAPPERR_BOINCNOGRAPHICSAPPSEXECUTING); // No GFX App is running: show moving BOINC logo m_hGraphicsApplication = 0; graphics_app_result_ptr = NULL; m_bDefault_gfx_running = false; m_bScience_gfx_running = false; #ifdef __APPLE__ launchedGfxApp("", 0, -1); #endif continue; } } } // end while(true) }
void qcnTrickleUp(const char* strTrickle, const int iVariety, const char* strWU) { // probably not thread safe, but within a same proc/thread (i.e. main.cpp) we should not have trickles/triggers sent within a second because BOINC // can't handle them that fast (i.e. writes out a trickle file name with a timestamp to the nearest second, and trickles within a second // write over each other static double dTimeLastTrickle = 0.0; // set time trickle sent so we can pause if necessary #ifdef QCNLIVE return; // no trickles on gui! #else // just a "sanity check" to make sure we haven't sent too many trickles in a row (i.e. > 1 sec) //trickleup::qcnCheckTrickleSleep(); double dCurTime = dtime(); if ((dCurTime - dTimeLastTrickle) < 1.0) { // last trickle sent less than a second ago, which would be bad for boinc, so sleep a bit) boinc_sleep((dCurTime - dTimeLastTrickle) + .10); } char strVariety[32]; memset(strVariety, 0x00, 32); strcpy(strVariety, "trigger"); switch (iVariety) { case TRIGGER_VARIETY_FINALSTATS: strcpy(strVariety, "finalstats"); break; case TRIGGER_VARIETY_QUAKELIST: strcpy(strVariety, "quakelist"); break; case TRIGGER_VARIETY_NORMAL: strcpy(strVariety, "trigger"); break; case TRIGGER_VARIETY_PING: strcpy(strVariety, "ping"); break; case TRIGGER_VARIETY_CONTINUAL: strcpy(strVariety, "continual"); break; } // BOINC adds the appropriate workunit/resultid etc and posts to trickle_up table in MySQL static bool bInHere = false; if (bInHere) return; bInHere = true; // CMC let's print out trickles in standalone mode so I can see something! if (boinc_is_standalone()) { char szTFile[32]; static unsigned long iNum = 0L; iNum++; sprintf(szTFile, "trickle_%09lu_%s.xml", (unsigned long) iNum, strVariety); FILE* fTrickle = boinc_fopen(szTFile, "w"); if (fTrickle) { fwrite(strTrickle, 1, strlen(strTrickle), fTrickle); fclose(fTrickle); } } else { boinc_send_trickle_up((char*) strVariety, (char*) strTrickle); } bInHere = false; #endif dTimeLastTrickle = dtime(); // set time trickle sent so we can pause if necessary }
int main(int argc, char **argv) { int retval; double fd; char output_path[512]; //, chkpt_path[512]; //FILE* state; retval = boinc_init(); if (retval) { fprintf(stderr, "boinc_init returned %d\n", retval); exit(retval); } // extract a --device option std::vector<char*> argVec; int cudaDevice = -1; for(int ii = 0; ii < argc; ii++) { if(cudaDevice < 0 && strcmp(argv[ii], "--device") == 0 && ii + 1 < argc) cudaDevice = atoi(argv[++ii]); else argVec.push_back(argv[ii]); } argc = (int)argVec.size(); argv = &argVec[0]; if(cudaDevice < 0) cudaDevice = 0; boinc_begin_critical_section(); // set the cuda device if ( rcuda::SetCudaDevice(cudaDevice) != 0 ) { fprintf(stderr, "Error setting device %u. Temporary exiting for 60 secs\n", cudaDevice); boinc_temporary_exitHack(); } cudaDeviceProp deviceProp; if(cudaGetDeviceProperties(&deviceProp, cudaDevice) == cudaErrorInvalidDevice) { fprintf(stderr, "Error querying device %u. Temporary exiting for 60 secs\n", cudaDevice); boinc_temporary_exitHack(); } #ifdef WIN32 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); #endif int buffCount = 0x2000; int chainSize = 100; if(deviceProp.major == 1) { /* buffCount = deviceProp.multiProcessorCount * 8;// 8 blocks per multiprocessor buffCount *= deviceProp.maxThreadsPerBlock / 64; // (BLOCK_X_SIZE) // buffCount *= 24; if(deviceProp.minor <= 1) buffCount *= 24; // 24 warps per multiprocessor for compute 1.0 and 1.1 else buffCount *= 32; // 32 warps per multiprocessor for compute 1.2 and 1.3 */ buffCount = 0x2000; } else if(deviceProp.major == 2) { chainSize = 200; /* buffCount = deviceProp.multiProcessorCount * 8;// 8 blocks per multiprocessor buffCount *= deviceProp.maxThreadsPerBlock / 64; //(BLOCK_X_SIZE) buffCount *= 32; // 48 warps per multiprocessor for compute 2.x /* if(deviceProp.minor == 1) { buffCount *= 2; } */ buffCount = 0x4000; } if(cudaDevice > 0) { chainSize = 1000; } if(argc < 10) { fprintf(stderr, "Not enough parameters"); return -1; } std::string sHashRoutineName, sCharsetName, sSalt, sCheckPoints; uint32 nRainbowChainCount, nPlainLenMin, nPlainLenMax, nRainbowTableIndex, nRainbowChainLen; uint64 nChainStart; sHashRoutineName = argv[1]; sCharsetName = argv[2]; nPlainLenMin = atoi(argv[3]); nPlainLenMax = atoi(argv[4]); nRainbowTableIndex = atoi(argv[5]); nRainbowChainLen = atoi(argv[6]); nRainbowChainCount = atoi(argv[7]); #ifdef _WIN32 nChainStart = _atoi64(argv[8]); #else nChainStart = atoll(argv[8]); #endif sCheckPoints = argv[9]; std::vector<int> vCPPositions; char *cp = strtok((char *)sCheckPoints.c_str(), ","); while(cp != NULL) { vCPPositions.push_back(atoi(cp)); cp = strtok(NULL, ","); } if(argc == 11) { sSalt = argv[10]; } //std::cout << "Starting ChainGenerator" << std::endl; // Setup CChainWalkContext //std::cout << "ChainGenerator started." << std::endl; if (!CChainWalkContext::SetHashRoutine(sHashRoutineName)) { fprintf(stderr, "hash routine %s not supported\n", sHashRoutineName.c_str()); return 1; } //std::cout << "Hash routine validated" << std::endl; if (!CChainWalkContext::SetPlainCharset(sCharsetName, nPlainLenMin, nPlainLenMax)) { std::cerr << "charset " << sCharsetName << " not supported" << std::endl; return 2; } //std::cout << "Plain charset validated" << std::endl; if (!CChainWalkContext::SetRainbowTableIndex(nRainbowTableIndex)) { std::cerr << "invalid rainbow table index " << nRainbowTableIndex << std::endl; return 3; } //std::cout << "Rainbowtable index validated" << std::endl; if(sHashRoutineName == "mscache")// || sHashRoutineName == "lmchall" || sHashRoutineName == "halflmchall") { // Convert username to unicode const char *szSalt = sSalt.c_str(); int salt_length = strlen(szSalt); unsigned char cur_salt[256]; for (int i=0; i<salt_length; i++) { cur_salt[i*2] = szSalt[i]; cur_salt[i*2+1] = 0x00; } CChainWalkContext::SetSalt(cur_salt, salt_length*2); } else if(sHashRoutineName == "halflmchall") { // The salt is hardcoded into the hash routine // CChainWalkContext::SetSalt((unsigned char*)&salt, 8); } else if(sHashRoutineName == "oracle") { CChainWalkContext::SetSalt((unsigned char *)sSalt.c_str(), sSalt.length()); } //std::cout << "Opening chain file" << std::endl; // Open file boinc_resolve_filename("result", output_path, sizeof(output_path)); fclose(boinc_fopen(output_path, "a")); FILE *outfile = boinc_fopen(output_path, "r+b"); if (outfile == NULL) { std::cerr << "failed to create " << output_path << std::endl; return 4; } // Check existing chains unsigned int nDataLen = (unsigned int)GetFileLen(outfile); // Round to boundary nDataLen = nDataLen / 10 * 10; if (nDataLen == nRainbowChainCount * 10) { std::cerr << "precomputation of this rainbow table already finished" << std::endl; fclose(outfile); return 0; } fseek(outfile, nDataLen, SEEK_SET); //XXX size_t isn't 32/64 clean size_t nReturn; CChainWalkContext cwc; uint64 nIndex[2]; //time_t tStart = time(NULL); // std::cout << "Starting to generate chains" << std::endl; int maxCalcBuffSize = rcuda::GetChainsBufferSize( buffCount ); std::cerr << "maxCalcBuffSize - estimated: " << buffCount << ". Chosen: " << maxCalcBuffSize << std::endl; uint64 *calcBuff = new uint64[2*maxCalcBuffSize]; int ii; CudaCWCExtender ex(&cwc); rcuda::RCudaTask cuTask; ex.Init(); for(int nCurrentCalculatedChains = nDataLen / 10, calcSize; nCurrentCalculatedChains < nRainbowChainCount; ) { fd = (double)nCurrentCalculatedChains / (double)nRainbowChainCount; boinc_fraction_done(fd); cuTask.hash = ex.GetHash(); cuTask.startIdx = nChainStart + nCurrentCalculatedChains; cuTask.idxCount = std::min<int>(nRainbowChainCount - nCurrentCalculatedChains, maxCalcBuffSize); cuTask.dimVec = ex.GetPlainDimVec(); cuTask.dimVecSize = ex.GetPlainDimVecSize()/2; cuTask.charSet = ex.GetCharSet(); cuTask.charSetSize = ex.GetCharSetSize(); cuTask.cpPositions = &vCPPositions[0]; cuTask.cpPosSize = vCPPositions.size(); cuTask.reduceOffset = ex.GetReduceOffset(); cuTask.plainSpaceTotal = ex.GetPlainSpaceTotal(); cuTask.rainbowChainLen = nRainbowChainLen; cuTask.kernChainSize = chainSize; for(ii = 0; ii < cuTask.idxCount; ii++) { calcBuff[2*ii] = cuTask.startIdx + ii; calcBuff[2*ii+1] = 0; } calcSize = rcuda::CalcChainsOnCUDA(&cuTask, calcBuff); BOINC_STATUS boinc_status; boinc_get_status(&boinc_status); if (boinc_status.quit_request || boinc_status.abort_request) { boinc_end_critical_section(); while (1) boinc_sleep(1); } if(calcSize > 0) { nCurrentCalculatedChains += calcSize; for(ii = 0; ii < cuTask.idxCount; ii++) { nIndex[0] = cuTask.startIdx + ii; // nReturn = fwrite(nIndex, 1, 8, outfile); nReturn = fwrite(calcBuff+(2*ii), 1, 8, outfile); nReturn += fwrite(calcBuff+(2*ii+1), 1, 2, outfile); if(nReturn != 10) { std::cerr << "disk write fail" << std::endl; fclose(outfile); return 9; } } } else { std::cerr << "Calculations on CUDA failed!" << std::endl; fclose(outfile); return -1; } } delete [] calcBuff; #ifdef _DEBUG std::cout << "Generation completed" << std::endl; #endif fclose(outfile); boinc_fraction_done(1); boinc_finish(0); }
void CBOINCClientManager::ShutdownBOINCCore(bool ShuttingDownManager) { wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::ShutdownBOINCCore - Function Begin")); CMainDocument* pDoc = wxGetApp().GetDocument(); wxInt32 iCount = 0; bool bClientQuit = false; wxString strConnectedCompter = wxEmptyString; wxString strPassword = wxEmptyString; double startTime = 0; wxDateTime zeroTime = wxDateTime((time_t)0); wxDateTime rpcCompletionTime = zeroTime; ASYNC_RPC_REQUEST request; int quit_result; wxASSERT(pDoc); wxASSERT(wxDynamicCast(pDoc, CMainDocument)); #ifdef __WXMAC__ // Mac Manager shuts down client only if Manager started client if (!m_bBOINCStartedByManager) return; #endif #ifdef __WXMSW__ if (IsBOINCConfiguredAsDaemon()) { stop_daemon_via_daemonctrl(); bClientQuit = true; } else #endif { pDoc->GetConnectedComputerName(strConnectedCompter); if (!pDoc->IsComputerNameLocal(strConnectedCompter)) { RPC_CLIENT rpc; if (!rpc.init("localhost")) { pDoc->m_pNetworkConnection->GetLocalPassword(strPassword); rpc.authorize((const char*)strPassword.mb_str()); if (IsBOINCCoreRunning()) { rpc.quit(); for (iCount = 0; iCount <= 10; iCount++) { if (!bClientQuit && !IsBOINCCoreRunning()) { wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - (localhost) Application Exit Detected")); bClientQuit = true; break; } wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - (localhost) Application Exit NOT Detected, Sleeping...")); ::wxSleep(1); } } else { bClientQuit = true; } } rpc.close(); } else { if (IsBOINCCoreRunning()) { if (ShuttingDownManager) { // Set event filtering to allow RPC completion // events but not events which start new RPCs wxGetApp().SetEventFiltering(true); } quit_result = -1; request.clear(); request.which_rpc = RPC_QUIT; request.rpcType = RPC_TYPE_ASYNC_NO_REFRESH; request.completionTime = &rpcCompletionTime; request.resultPtr = &quit_result; pDoc->RequestRPC(request); // Issue an asynchronous Quit RPC // Client needs time to shut down project applications, so don't wait // for it to shut down; assume it will exit OK if Quit RPC succeeds. startTime = dtime(); while ((dtime() - startTime) < 10.0) { // Allow 10 seconds boinc_sleep(0.25); // Check 4 times per second wxSafeYield(NULL, true); // To allow handling RPC completion events if (!bClientQuit && (rpcCompletionTime != zeroTime)) { // If Quit RPC finished, check its returned value if (quit_result) { break; // Quit RPC returned an error } wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - Application Exit Detected")); bClientQuit = true; break; } wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - Application Exit NOT Detected, Sleeping...")); } } else { bClientQuit = true; } } } if (!bClientQuit) { KillClient(); } m_lBOINCCoreProcessId = 0; wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::ShutdownBOINCCore - Function End")); }
bool CBOINCClientManager::StartupBOINCCore() { wxLogTrace(wxT("Function Start/End"), wxT("CMainDocument::StartupBOINCCore - Function Begin")); bool bReturnValue = false; wxString strExecute = wxEmptyString; if (IsBOINCCoreRunning()) return true; #if defined(__WXMSW__) LPTSTR szExecute = NULL; LPTSTR szDataDirectory = NULL; if (IsBOINCConfiguredAsDaemon()) { return (!!StartBOINCService()); } // Append synecd.exe to the end of the strExecute string strExecute.Printf( wxT("\"%ssynecd.exe\" --redirectio --launched_by_manager %s"), wxGetApp().GetRootDirectory().c_str(), wxGetApp().GetArguments().c_str() ); PROCESS_INFORMATION pi; STARTUPINFO si; BOOL bProcessStarted; memset(&pi, 0, sizeof(pi)); memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; szExecute = (LPTSTR)strExecute.c_str(); if (wxGetApp().GetDataDirectory().empty()) { szDataDirectory = NULL; } else { szDataDirectory = (LPTSTR)wxGetApp().GetDataDirectory().c_str(); } wxLogTrace(wxT("Function Status"), wxT("CMainDocument::StartupBOINCCore - szExecute '%s'\n"), szExecute); wxLogTrace(wxT("Function Status"), wxT("CMainDocument::StartupBOINCCore - szDataDirectory '%s'\n"), szDataDirectory); bProcessStarted = CreateProcess( NULL, szExecute, NULL, NULL, FALSE, CREATE_NEW_PROCESS_GROUP|CREATE_NO_WINDOW, NULL, szDataDirectory, &si, &pi ); if (bProcessStarted) { m_lBOINCCoreProcessId = pi.dwProcessId; m_hBOINCCoreProcess = pi.hProcess; } #elif defined(__WXMAC__) char buf[1024]; char *argv[5]; ProcessSerialNumber ourPSN; FSRef ourFSRef; OSErr err; if (IsBOINCConfiguredAsDaemon() == NewStyleDaemon) { system ("launchctl load /Library/LaunchDaemons/com.googlecode.synecdoche.plist"); system ("launchctl start com.googleccode.synecdoche"); bReturnValue = IsBOINCCoreRunning(); } else { // Get the full path to core client inside this application's bundle err = GetCurrentProcess (&ourPSN); if (err == noErr) { err = GetProcessBundleLocation(&ourPSN, &ourFSRef); } if (err == noErr) { err = FSRefMakePath (&ourFSRef, (UInt8*)buf, sizeof(buf)); } if (err == noErr) { #if 0 // The Mac version of wxExecute(wxString& ...) crashes if there is a space in the path strExecute = wxT("\""); strExecute += wxT(buf); strExecute += wxT("/Contents/Resources/synecd\" --redirectio --launched_by_manager"); m_lBOINCCoreProcessId = ::wxExecute(strExecute); #else // Use wxExecute(wxChar **argv ...) instead of wxExecute(wxString& ...) strcat(buf, "/Contents/Resources/synecd"); argv[0] = buf; argv[1] = "--redirectio"; argv[2] = "--launched_by_manager"; argv[3] = NULL; #ifdef SANDBOX if (!g_use_sandbox) { argv[3] = "--insecure"; argv[4] = NULL; } #endif // Under wxMac-2.8.0, wxExecute starts a separate thread // to wait for child's termination. // That wxProcessTerminationThread uses a huge amount of processor // time (about 11% of one CPU on 2GHz Intel Dual-Core Mac). // m_lBOINCCoreProcessId = ::wxExecute(argv); run_program( "/Library/Application Support/Synecdoche Data", buf, argv[3] ? 4 : 3, argv, 0.0, m_lBOINCCoreProcessId ); #endif } else { buf[0] = '\0'; } } #else // Unix based systems // Append boinc.exe to the end of the strExecute string and get ready to rock strExecute = ::wxGetCwd() + wxT("/boinc --redirectio --launched_by_manager"); #ifdef SANDBOX if (!g_use_sandbox) { strExecute += wxT(" --insecure"); } #endif // SANDBOX wxLogTrace(wxT("Function Status"), wxT("CMainDocument::StartupBOINCCore - szExecute '%s'\n"), strExecute.c_str()); wxLogTrace(wxT("Function Status"), wxT("CMainDocument::StartupBOINCCore - szDataDirectory '%s'\n"), ::wxGetCwd().c_str()); m_lBOINCCoreProcessId = ::wxExecute(strExecute); #endif if (0 != m_lBOINCCoreProcessId) { m_bBOINCStartedByManager = true; bReturnValue = true; // Allow time for daemon to start up so we don't keep relaunching it for (int i = 0; i < 100; ++i) { // Wait up to 4 seconds in 40ms increments if (IsBOINCCoreRunning()) { break; } boinc_sleep(0.04); } } wxLogTrace(wxT("Function Start/End"), wxT("CMainDocument::StartupBOINCCore - Function End")); return bReturnValue; }
/// Start a task in a slot directory. /// This includes setting up soft links, /// passing preferences, and starting the process. /// /// Current dir is top-level Synecdoche dir. /// /// \post /// - If any error occurs /// - #task_state is #PROCESS_COULDNT_START /// - CLIENT_STATE::report_result_error() is called /// - else /// - #task_state is #PROCESS_EXECUTING /// /// \return 0 on success, nonzero otherwise. int ACTIVE_TASK::start() { char exec_name[256], exec_path[256]; unsigned int i; FILE_REF fref; int retval; // F*** goto, need to define some variables here instead of where they are used! std::ostringstream err_stream; #ifdef _WIN32 std::string cmd_line; std::string slotdirpath; #else // Needs to be defined here because those gotos would skip the // initialization of 'cmdline' and 'argv' if it would be defined later. std::ostringstream cmdline; std::list<std::string> argv; #endif if ((!full_init_done) && (log_flags.task)) { msg_printf(wup->project, MSG_INFO, "Starting %s", result->name ); } if (log_flags.cpu_sched) { msg_printf(wup->project, MSG_INFO, "[cpu_sched] Starting %s%s", result->name, (full_init_done) ? " (resume)" : " (initial)" ); } // Always check if all required files are present. If not, trigger // re-downloads and don't start the science application. FILE_INFO_PSET missing_file_infos; retval = gstate.input_files_available(result, true, &missing_file_infos); if (retval) { for (FILE_INFO_PSET::iterator it = missing_file_infos.begin(); it != missing_file_infos.end(); ++it) { FILE_INFO* fip = *it; if (fip) { err_stream << "Input file " << fip->name << " missing or invalid: " << retval; } else { err_stream << "Input file missing or invalid"; // We can't trigger a new download if we don't have // any file information. Just fail here as before. goto error; } fip->status = FILE_NOT_PRESENT; } } if (!missing_file_infos.empty()) { // Some files are missing and are set for re-transfer. // Update status and return without error. result->set_state(RESULT_FILES_DOWNLOADING, "start"); set_task_state(PROCESS_UNINITIALIZED, "start"); next_scheduler_state = PROCESS_UNINITIALIZED; return 0; } if (!full_init_done) { checkpoint_cpu_time = 0; checkpoint_wall_time = gstate.now; } current_cpu_time = checkpoint_cpu_time; episode_start_cpu_time = checkpoint_cpu_time; debt_interval_start_cpu_time = checkpoint_cpu_time; graphics_request_queue.init(result->name); // reset message queues process_control_queue.init(result->name); if (!app_client_shm.shm) { retval = get_shmem_seg_name(); if (retval) { err_stream << "Can't get shared memory segment name: " << boincerror(retval); goto error; } } // this must go AFTER creating shmem name, // since the shmem name is part of the file // retval = write_app_init_file(); if (retval) { err_stream << "Can't write init file: " << retval; goto error; } // set up applications files // strcpy(exec_name, ""); for (i=0; i<app_version->app_files.size(); i++) { fref = app_version->app_files[i]; FILE_INFO* fip = fref.file_info; std::string file_path = get_pathname(fip); if (fref.main_program) { if (is_image_file(fip->name)) { err_stream << "Main program " << fip->name << " is an image file"; retval = ERR_NO_SIGNATURE; goto error; } if (!fip->executable && !wup->project->anonymous_platform) { err_stream << "Main program " << fip->name << " is not executable"; retval = ERR_NO_SIGNATURE; goto error; } safe_strcpy(exec_name, fip->name.c_str()); safe_strcpy(exec_path, file_path.c_str()); } // anonymous platform may use different files than // when the result was started, so link files even if not first time if ((!full_init_done) || (wup->project->anonymous_platform)) { retval = setup_file(result->project, fip, fref, file_path, slot_dir, true); if (retval) { err_stream << "Can't link input file"; goto error; } } } if (!strlen(exec_name)) { err_stream << "No main program specified"; retval = ERR_NOT_FOUND; goto error; } // set up input, output files if (!full_init_done) { for (i=0; i<wup->input_files.size(); i++) { fref = wup->input_files[i]; const FILE_INFO* fip = fref.file_info; std::string file_path = get_pathname(fref.file_info); retval = setup_file(result->project, fip, fref, file_path, slot_dir, true); if (retval) { err_stream << "Can't link input file"; goto error; } } for (i=0; i<result->output_files.size(); i++) { fref = result->output_files[i]; if (fref.copy_file) continue; const FILE_INFO* fip = fref.file_info; std::string file_path = get_pathname(fref.file_info); retval = setup_file(result->project, fip, fref, file_path, slot_dir, false); if (retval) { err_stream << "Can't link output file"; goto error; } } full_init_done = true; } link_user_files(); if (gstate.exit_before_start) { exit(0); } #ifdef _WIN32 PROCESS_INFORMATION process_info; STARTUPINFO startup_info; LPVOID environment_block = NULL; char error_msg[1024]; char error_msg2[1024]; memset(&process_info, 0, sizeof(process_info)); memset(&startup_info, 0, sizeof(startup_info)); startup_info.cb = sizeof(startup_info); // suppress 2-sec rotating hourglass cursor on startup // startup_info.dwFlags = STARTF_FORCEOFFFEEDBACK; app_client_shm.reset_msgs(); if (config.run_apps_manually) { // fill in core client's PID so we won't think app has exited pid = GetCurrentProcessId(); pid_handle = GetCurrentProcess(); set_task_state(PROCESS_EXECUTING, "start"); return 0; } // NOTE: in Windows, stderr is redirected in boinc_init_diagnostics(); cmd_line = exec_path + std::string(" ") + wup->command_line; if (strlen(app_version->cmdline)) { cmd_line += std::string(" ") + app_version->cmdline; } slotdirpath = relative_to_absolute(slot_dir); bool success = false; for (i=0; i<5; i++) { if (sandbox_account_service_token != NULL) { // Find CreateEnvironmentBlock/DestroyEnvironmentBlock pointers tCEB pCEB = NULL; tDEB pDEB = NULL; HMODULE hUserEnvLib = NULL; hUserEnvLib = LoadLibrary("userenv.dll"); if (hUserEnvLib) { pCEB = (tCEB) GetProcAddress(hUserEnvLib, "CreateEnvironmentBlock"); pDEB = (tDEB) GetProcAddress(hUserEnvLib, "DestroyEnvironmentBlock"); } if (!pCEB(&environment_block, sandbox_account_service_token, FALSE)) { if (log_flags.task) { windows_error_string(error_msg, sizeof(error_msg)); msg_printf(wup->project, MSG_INFO, "Process environment block creation failed: %s", error_msg ); } } if (CreateProcessAsUser( sandbox_account_service_token, exec_path, (LPSTR)cmd_line.c_str(), NULL, NULL, FALSE, CREATE_NEW_PROCESS_GROUP|CREATE_NO_WINDOW|IDLE_PRIORITY_CLASS|CREATE_UNICODE_ENVIRONMENT, environment_block, slotdirpath.c_str(), &startup_info, &process_info )) { success = true; break; } else { windows_error_string(error_msg, sizeof(error_msg)); msg_printf(wup->project, MSG_INTERNAL_ERROR, "Process creation failed: %s", error_msg ); } if (!pDEB(environment_block)) { if (log_flags.task) { windows_error_string(error_msg, sizeof(error_msg2)); msg_printf(wup->project, MSG_INFO, "Process environment block cleanup failed: %s", error_msg2 ); } } if (hUserEnvLib) { pCEB = NULL; pDEB = NULL; FreeLibrary(hUserEnvLib); } } else { if (CreateProcess( exec_path, (LPSTR)cmd_line.c_str(), NULL, NULL, FALSE, CREATE_NEW_PROCESS_GROUP|CREATE_NO_WINDOW|IDLE_PRIORITY_CLASS, NULL, slotdirpath.c_str(), &startup_info, &process_info )) { success = true; break; } else { windows_error_string(error_msg, sizeof(error_msg)); msg_printf(wup->project, MSG_INTERNAL_ERROR, "Process creation failed: %s", error_msg ); } } boinc_sleep(drand()); } if (!success) { err_stream << "CreateProcess() failed - " << error_msg; retval = ERR_EXEC; goto error; } pid = process_info.dwProcessId; pid_handle = process_info.hProcess; CloseHandle(process_info.hThread); // thread handle is not used #else // Unix/Linux/Mac case // Set up core/app shared memory seg if needed // if (!app_client_shm.shm) { if (app_version->api_major_version() >= 6) { // Use mmap() shared memory std::string buf = slot_dir + std::string("/") + std::string(MMAPPED_FILE_NAME); if (g_use_sandbox) { if (!boinc_file_exists(buf.c_str())) { int fd = open(buf.c_str(), O_RDWR | O_CREAT, 0660); if (fd >= 0) { close (fd); #ifdef SANDBOX set_to_project_group(buf.c_str()); #endif } } } retval = create_shmem_mmap( buf.c_str(), sizeof(SHARED_MEM), (void**)&app_client_shm.shm ); } else { // Use shmget() shared memory retval = create_shmem( shmem_seg_name, sizeof(SHARED_MEM), gstate.boinc_project_gid, (void**)&app_client_shm.shm ); if (retval) { needs_shmem = true; destroy_shmem(shmem_seg_name); return retval; } } needs_shmem = false; } app_client_shm.reset_msgs(); #if (defined (__APPLE__) && (defined(__i386__) || defined(__x86_64__))) // PowerPC apps emulated on i386 Macs crash if running graphics powerpc_emulated_on_i386 = ! is_native_i386_app(exec_path); #endif if (config.run_apps_manually) { pid = getpid(); // use the client's PID set_task_state(PROCESS_EXECUTING, "start"); return 0; } // Prepare command line for the science app: cmdline << wup->command_line; if (strlen(app_version->cmdline)) { cmdline << ' ' << app_version->cmdline; } argv = parse_command_line(cmdline.str().c_str()); if (log_flags.task_debug) { debug_print_argv(argv); } pid = fork(); if (pid == -1) { err_stream << "fork() failed: " << strerror(errno); retval = ERR_FORK; goto error; } if (pid == 0) { // from here on we're running in a new process. // If an error happens, // exit nonzero so that the core client knows there was a problem. // don't pass stdout to the app // int fd = open("/dev/null", O_RDWR); dup2(fd, STDOUT_FILENO); close(fd); // add to library path: // - the project dir (../../projects/X) // - the slot dir (.) // - the Synecdoche dir (../..) // We use relative paths in case higher-level dirs // are not readable to the account under which app runs // std::string pdir = get_project_dir(wup->project); std::ostringstream libpath; const char* env_lib_path = getenv("LD_LIBRARY_PATH"); if (env_lib_path) { libpath << env_lib_path << ':'; } libpath << "../../" << pdir << ":.:../.."; setenv("LD_LIBRARY_PATH", libpath.str().c_str(), 1); retval = chdir(slot_dir.c_str()); if (retval) { perror("chdir"); fflush(NULL); _exit(errno); } #if 0 // set stack size limit to the max. // Some BOINC apps have reported problems with exceeding // small stack limits (e.g. 8 MB) // and it seems like the best thing to raise it as high as possible // struct rlimit rlim; #define MIN_STACK_LIMIT 64000000 getrlimit(RLIMIT_STACK, &rlim); if (rlim.rlim_cur != RLIM_INFINITY && rlim.rlim_cur <= MIN_STACK_LIMIT) { if (rlim.rlim_max == RLIM_INFINITY || rlim.rlim_max > MIN_STACK_LIMIT) { rlim.rlim_cur = MIN_STACK_LIMIT; } else { rlim.rlim_cur = rlim.rlim_max; } setrlimit(RLIMIT_STACK, &rlim); } #endif // hook up stderr to a specially-named file // freopen(STDERR_FILE, "a", stderr); // set idle process priority #ifdef HAVE_SETPRIORITY if (setpriority(PRIO_PROCESS, 0, PROCESS_IDLE_PRIORITY)) { perror("setpriority"); } #endif std::string path = std::string("../../") + std::string(exec_path); if (g_use_sandbox) { std::ostringstream switcher_path; switcher_path << "../../" << SWITCHER_DIR << '/' << SWITCHER_FILE_NAME; argv.push_front(exec_name); argv.push_front(path); argv.push_front(SWITCHER_FILE_NAME); // Files written by projects have user boinc_project and group boinc_project, // so they must be world-readable so Synecdoche can read them. umask(2); retval = do_execv(switcher_path.str(), argv); } else { argv.push_front(exec_name); retval = do_execv(path, argv); } msg_printf(wup->project, MSG_INTERNAL_ERROR, "Process creation (%s) failed: %s, errno=%d\n", path.c_str(), boincerror(retval), errno ); perror("execv"); fflush(NULL); _exit(errno); } if (log_flags.task_debug) { msg_printf(wup->project, MSG_INFO, "[task_debug] ACTIVE_TASK::start(): forked process: pid %d\n", pid ); } #endif set_task_state(PROCESS_EXECUTING, "start"); return 0; // go here on error; "error_msg" contains error message, "retval" is nonzero // error: // if something failed, it's possible that the executable was munged. // Verify it to trigger another download. // gstate.input_files_available(result, true); gstate.report_result_error(*result, "%s", err_stream.str().c_str()); set_task_state(PROCESS_COULDNT_START, "start"); return retval; }
int main(int argc, char** argv) { BOINC_OPTIONS boinc_options; BOINC_STATUS boinc_status; char buf[256]; int retval; memset(&boinc_options, 0, sizeof(boinc_options)); boinc_options.main_program = true; boinc_options.check_heartbeat = true; boinc_options.handle_process_control = true; boinc_init_options(&boinc_options); fprintf( stderr, "%s vboxwrapper: starting\n", boinc_msg_prefix(buf, sizeof(buf)) ); retval = parse_job_file(); if (retval) { fprintf( stderr, "%s can't parse job file: %d\n", boinc_msg_prefix(buf, sizeof(buf)), retval ); boinc_finish(retval); } retval = vm.run(); if (retval) { boinc_finish(retval); } while (1) { vm.poll(); boinc_get_status(&boinc_status); if (boinc_status.no_heartbeat || boinc_status.quit_request) { vm.stop(); boinc_temporary_exit(0); } if (boinc_status.abort_request) { vm.cleanup(); boinc_finish(EXIT_ABORTED_BY_CLIENT); } if (!vm.is_running()) { vm.cleanup(); boinc_finish(0); } if (boinc_status.suspended) { if (!vm.suspended) { vm.pause(); } } else { if (vm.suspended) { vm.resume(); } } boinc_sleep(POLL_PERIOD); } return 0; }
// Terminate any screensaver graphics application // int CScreensaver::terminate_v6_screensaver(GFXAPP_ID& graphics_application) { int retval = 0; #ifdef __APPLE__ // Under sandbox security, use gfx_switcher to kill default gfx app // as user boinc_master and group boinc_master. The man page for // kill() says the user ID of the process sending the signal must // match that of the target process, though in practice that seems // not to be true on the Mac. char current_dir[PATH_MAX]; char gfx_pid[16]; pid_t thePID; int i; if (graphics_application == 0) return 0; // MUTEX may help prevent crashes when terminating an older gfx app which // we were displaying using CGWindowListCreateImage under OS X >= 10.13 // Also prevents reentry when called from our other thread pthread_mutex_lock(&saver_mutex); sprintf(gfx_pid, "%d", graphics_application); getcwd( current_dir, sizeof(current_dir)); char* argv[4]; argv[0] = "gfx_switcher"; argv[1] = "-kill_gfx"; argv[2] = gfx_pid; argv[3] = 0; retval = run_program( current_dir, m_gfx_Switcher_Path, 3, argv, 0, thePID ); if (graphics_application) { launchedGfxApp("", 0, -1); } for (i=0; i<200; i++) { boinc_sleep(0.01); // Wait 2 seconds max // Prevent gfx_switcher from becoming a zombie if (waitpid(thePID, 0, WNOHANG) == thePID) { break; } } pthread_mutex_unlock(&saver_mutex); #endif #ifdef _WIN32 HWND hBOINCGraphicsWindow = FindWindow(BOINC_WINDOW_CLASS_NAME, NULL); if (hBOINCGraphicsWindow) { CloseWindow(hBOINCGraphicsWindow); Sleep(1000); hBOINCGraphicsWindow = FindWindow(BOINC_WINDOW_CLASS_NAME, NULL); if (hBOINCGraphicsWindow) { kill_program(graphics_application); } } #endif // For safety, call kill_program even under Apple sandbox security kill_program(graphics_application); return retval; }
// Write the client_state.xml file // int CLIENT_STATE::write_state_file() { MFILE mf; int retval, ret1, ret2, attempt; #ifdef _WIN32 char win_error_msg[4096]; #endif for (attempt=1; attempt<=MAX_STATE_FILE_WRITE_ATTEMPTS; attempt++) { if (attempt > 1) boinc_sleep(1.0); if (log_flags.statefile_debug) { msg_printf(0, MSG_INFO, "[statefile] Writing state file" ); } #ifdef _WIN32 retval = mf.open(STATE_FILE_NEXT, "wc"); #else retval = mf.open(STATE_FILE_NEXT, "w"); #endif if (retval) { if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.statefile_debug) { msg_printf(0, MSG_INTERNAL_ERROR, "Can't open %s: %s", STATE_FILE_NEXT, boincerror(retval) ); } if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue; return ERR_FOPEN; } MIOFILE miof; miof.init_mfile(&mf); ret1 = write_state(miof); ret2 = mf.close(); if (ret1) { if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.statefile_debug) { msg_printf(NULL, MSG_INTERNAL_ERROR, "Couldn't write state file: %s", boincerror(retval) ); } if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue; return ret1; } if (ret2) { if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue; return ret2; } // only attempt to rename the current state file if it exists. // if (boinc_file_exists(STATE_FILE_NAME)) { if (boinc_file_exists(STATE_FILE_PREV)) { retval = boinc_delete_file(STATE_FILE_PREV); if (retval) { if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.statefile_debug) { #ifdef _WIN32 msg_printf(0, MSG_INFO, "Can't delete previous state file; %s", windows_format_error_string(GetLastError(), win_error_msg, sizeof(win_error_msg)) ); #else msg_printf(0, MSG_INFO, "Can't delete previous state file: %s", strerror(errno) ); #endif } if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue; } } retval = boinc_rename(STATE_FILE_NAME, STATE_FILE_PREV); if (retval) { if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.statefile_debug) { #ifdef _WIN32 msg_printf(0, MSG_INFO, "Can't rename current state file to previous state file; %s", windows_format_error_string(GetLastError(), win_error_msg, sizeof(win_error_msg)) ); #else msg_printf(0, MSG_INFO, "Can't rename current state file to previous state file: %s", strerror(errno) ); #endif } if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue; } } retval = boinc_rename(STATE_FILE_NEXT, STATE_FILE_NAME); if (log_flags.statefile_debug) { msg_printf(0, MSG_INFO, "[statefile] Done writing state file" ); } if (!retval) break; // Success! if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.statefile_debug) { #ifdef _WIN32 msg_printf(0, MSG_INFO, "rename error: %s", windows_format_error_string(GetLastError(), win_error_msg, sizeof(win_error_msg)) ); #elif defined (__APPLE__) if (log_flags.statefile_debug) { system("ls -al /Library/Application\\ Support/BOINC\\ Data/client*.*"); } #endif } if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue; return ERR_RENAME; } return 0; }
void CBOINCBaseFrame::ShowConnectionFailedAlert() { CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced(); CMainDocument* pDoc = wxGetApp().GetDocument(); wxString strConnectedCompter = wxEmptyString; wxString strDialogTitle = wxEmptyString; wxString strDialogMessage = wxEmptyString; wxASSERT(pSkinAdvanced); wxASSERT(wxDynamicCast(pSkinAdvanced, CSkinAdvanced)); wxASSERT(pDoc); wxASSERT(wxDynamicCast(pDoc, CMainDocument)); wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::ShowConnectionFailedAlert - Function Begin")); // Did BOINC crash on local computer? If so restart it and reconnect. pDoc->GetConnectedComputerName(strConnectedCompter); if (pDoc->IsComputerNameLocal(strConnectedCompter)) { if (pDoc->m_pClientManager->AutoRestart()) { boinc_sleep(0.5); // Allow time for Client to restart if (pDoc->m_pClientManager->IsBOINCCoreRunning()) { pDoc->Reconnect(); return; } } else { // Don't ask whether to reconnect to local client if it is not running if (!pDoc->m_pClientManager->IsBOINCCoreRunning()) { return; } } } // %s is the application name // i.e. 'BOINC Manager', 'GridRepublic Manager' strDialogTitle.Printf( _("%s - Connection Failed"), pSkinAdvanced->GetApplicationName().c_str() ); // 1st %s is the application name // i.e. 'BOINC Manager', 'GridRepublic Manager' // 2st %s is the project name // i.e. 'BOINC', 'GridRepublic' strDialogMessage.Printf( _("%s is not able to connect to a %s client.\nWould you like to try to connect again?"), pSkinAdvanced->GetApplicationName().c_str(), pSkinAdvanced->GetApplicationShortName().c_str() ); ShowAlert( strDialogTitle, strDialogMessage, wxYES_NO | wxICON_QUESTION, false, AlertProcessResponse ); // If we are minimized, set flag to show alert when maximized m_bShowConnectionFailedAlert = !IsShown(); wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::ShowConnectionFailedAlert - Function End")); }