mirror of https://github.com/BOINC/boinc.git
- MGR: Change the CC startup logic so that more informative error
messages. Policy Change: When installed as a service or daemon, the service or daemon manager should start BOINC, not the BOINC Manager. (Windows Only for right now, should eventually be applied to all platforms) - LIB: Undue my previous change that launched graphics apps as an idle process. - LIB: Take care of some warnings. clientgui/ BOINCBaseFrame.cpp, .h BOINCClientManager.cpp, .h (Added) BOINCGUIApp.cpp, .h MainDocument.cpp, .h lib/ util.C svn path=/trunk/boinc/; revision=14647
This commit is contained in:
parent
23c333bac2
commit
58e4094892
|
@ -930,3 +930,23 @@ Charlie Jan 29 2008
|
|||
lib/
|
||||
gui_rpc_client.h
|
||||
gui_rpc_client_ops.C
|
||||
|
||||
Rom Jan 30 2008
|
||||
- MGR: Change the CC startup logic so that more informative error
|
||||
messages.
|
||||
|
||||
Policy Change: When installed as a service or daemon, the service
|
||||
or daemon manager should start BOINC, not the BOINC Manager.
|
||||
(Windows Only for right now, should eventually be applied
|
||||
to all platforms)
|
||||
- LIB: Undue my previous change that launched graphics apps as
|
||||
an idle process.
|
||||
- LIB: Take care of some warnings.
|
||||
|
||||
clientgui/
|
||||
BOINCBaseFrame.cpp, .h
|
||||
BOINCClientManager.cpp, .h (Added)
|
||||
BOINCGUIApp.cpp, .h
|
||||
MainDocument.cpp, .h
|
||||
lib/
|
||||
util.C
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "BOINCGUIApp.h"
|
||||
#include "SkinManager.h"
|
||||
#include "MainDocument.h"
|
||||
#include "BOINCClientManager.h"
|
||||
#include "BOINCTaskBar.h"
|
||||
#include "BOINCBaseFrame.h"
|
||||
#include "BOINCDialupManager.h"
|
||||
|
@ -177,16 +178,6 @@ void CBOINCBaseFrame::OnAlertPoll(wxTimerEvent& WXUNUSED(event)) {
|
|||
|
||||
void CBOINCBaseFrame::OnInitialized(CFrameEvent& WXUNUSED(event)) {
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::OnInitialized - Function Begin"));
|
||||
|
||||
CMainDocument* pDoc = wxGetApp().GetDocument();
|
||||
|
||||
wxASSERT(pDoc);
|
||||
wxASSERT(wxDynamicCast(pDoc, CMainDocument));
|
||||
|
||||
if (!pDoc->IsConnected()) {
|
||||
pDoc->Connect(wxT("localhost"), wxEmptyString, TRUE, TRUE);
|
||||
}
|
||||
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::OnInitialized - Function End"));
|
||||
}
|
||||
|
||||
|
@ -407,7 +398,7 @@ void CBOINCBaseFrame::ShowConnectionFailedAlert() {
|
|||
|
||||
|
||||
// Did BOINC crash? If so restart it.
|
||||
wxGetApp().AutoRestartBOINC();
|
||||
wxGetApp().GetDocument()->m_pClientManager->AutoRestart();
|
||||
|
||||
|
||||
// %s is the application name
|
||||
|
@ -440,6 +431,57 @@ void CBOINCBaseFrame::ShowConnectionFailedAlert() {
|
|||
}
|
||||
|
||||
|
||||
void CBOINCBaseFrame::ShowDaemonStartFailedAlert() {
|
||||
CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced();
|
||||
wxString strDialogTitle = wxEmptyString;
|
||||
wxString strDialogMessage = wxEmptyString;
|
||||
|
||||
|
||||
wxASSERT(pSkinAdvanced);
|
||||
wxASSERT(wxDynamicCast(pSkinAdvanced, CSkinAdvanced));
|
||||
|
||||
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::ShowDaemonStartFailedAlert - Function Begin"));
|
||||
|
||||
|
||||
// %s is the application name
|
||||
// i.e. 'BOINC Manager', 'GridRepublic Manager'
|
||||
strDialogTitle.Printf(
|
||||
_("%s - Daemon Start 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'
|
||||
#ifdef __WXMSW__
|
||||
strDialogMessage.Printf(
|
||||
_("%s is not able to start a %s client.\n"
|
||||
"Please launch the Control Panel->Administative Tools->Services "
|
||||
"applet and start the BOINC service."),
|
||||
pSkinAdvanced->GetApplicationName().c_str(),
|
||||
pSkinAdvanced->GetApplicationShortName().c_str()
|
||||
);
|
||||
#else
|
||||
strDialogMessage.Printf(
|
||||
_("%s is not able to start a %s client.\n"
|
||||
"Please start the daemon and try again."),
|
||||
pSkinAdvanced->GetApplicationName().c_str(),
|
||||
pSkinAdvanced->GetApplicationShortName().c_str()
|
||||
);
|
||||
#endif
|
||||
|
||||
ShowAlert(
|
||||
strDialogTitle,
|
||||
strDialogMessage,
|
||||
wxOK | wxICON_ERROR
|
||||
);
|
||||
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::ShowDaemonStartFailedAlert - Function End"));
|
||||
}
|
||||
|
||||
|
||||
void CBOINCBaseFrame::ShowNotCurrentlyConnectedAlert() {
|
||||
CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced();
|
||||
wxString strDialogTitle = wxEmptyString;
|
||||
|
@ -454,7 +496,7 @@ void CBOINCBaseFrame::ShowNotCurrentlyConnectedAlert() {
|
|||
|
||||
|
||||
// Did BOINC crash? If so restart it.
|
||||
wxGetApp().AutoRestartBOINC();
|
||||
wxGetApp().GetDocument()->m_pClientManager->AutoRestart();
|
||||
|
||||
|
||||
// %s is the application name
|
||||
|
|
|
@ -71,6 +71,7 @@ public:
|
|||
void FireReloadSkin();
|
||||
void ShowConnectionBadPasswordAlert( bool bUsedDefaultPassword, int m_iReadGUIRPCAuthFailure );
|
||||
void ShowConnectionFailedAlert();
|
||||
void ShowDaemonStartFailedAlert();
|
||||
void ShowNotCurrentlyConnectedAlert();
|
||||
|
||||
virtual void StartTimers();
|
||||
|
|
|
@ -0,0 +1,469 @@
|
|||
// Berkeley Open Infrastructure for Network Computing
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2005 University of California
|
||||
//
|
||||
// This is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation;
|
||||
// either version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This software is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// To view the GNU Lesser General Public License visit
|
||||
// http://www.gnu.org/copyleft/lesser.html
|
||||
// or write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#if defined(__GNUG__) && !defined(__APPLE__)
|
||||
#pragma implementation "BOINCClientManager.h"
|
||||
#endif
|
||||
|
||||
#include "stdwx.h"
|
||||
#include "diagnostics.h"
|
||||
#include "LogBOINC.h"
|
||||
#include "BOINCGUIApp.h"
|
||||
#include "MainDocument.h"
|
||||
#include "BOINCBaseFrame.h"
|
||||
#include "AdvancedFrame.h"
|
||||
#include "BOINCClientManager.h"
|
||||
|
||||
|
||||
#ifdef __WXMSW__
|
||||
EXTERN_C BOOL IsBOINCServiceInstalled();
|
||||
EXTERN_C BOOL IsBOINCServiceStarting();
|
||||
EXTERN_C BOOL IsBOINCServiceRunning();
|
||||
EXTERN_C BOOL IsBOINCServiceStopping();
|
||||
EXTERN_C BOOL IsBOINCServiceStopped();
|
||||
EXTERN_C BOOL StartBOINCService();
|
||||
EXTERN_C BOOL StopBOINCService();
|
||||
#endif
|
||||
|
||||
|
||||
CBOINCClientManager::CBOINCClientManager() {
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::CBOINCClientManager - Function Begin"));
|
||||
|
||||
m_bBOINCStartedByManager = false;
|
||||
m_bClientRunningAsDaemon = false;
|
||||
m_lBOINCCoreProcessId = 0;
|
||||
|
||||
#ifdef __WXMSW__
|
||||
m_hBOINCCoreProcess = NULL;
|
||||
#endif
|
||||
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::CBOINCClientManager - Function End"));
|
||||
}
|
||||
|
||||
|
||||
CBOINCClientManager::~CBOINCClientManager() {
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::~CBOINCClientManager - Function Begin"));
|
||||
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::~CBOINCClientManager - Function End"));
|
||||
}
|
||||
|
||||
|
||||
bool CBOINCClientManager::AutoRestart() {
|
||||
if (!IsBOINCCoreRunning() && m_bBOINCStartedByManager) {
|
||||
StartupBOINCCore();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CBOINCClientManager::IsSystemBooting() {
|
||||
bool bReturnValue = false;
|
||||
#if defined(__WXMSW__)
|
||||
if (GetTickCount() < (1000*60*5)) bReturnValue = true; // If system has been up for less than 5 minutes
|
||||
#elif defined(__WXMAC__)
|
||||
if (TickCount() < (120*60)) bReturnValue = true; // If system has been up for less than 2 minutes
|
||||
#endif
|
||||
return bReturnValue;
|
||||
}
|
||||
|
||||
|
||||
bool CBOINCClientManager::IsBOINCDaemon() {
|
||||
bool bReturnValue = false;
|
||||
#if defined(__WXMSW__)
|
||||
if (IsBOINCServiceInstalled()) bReturnValue = true;
|
||||
#elif defined(__WXMAC__)
|
||||
if ( boinc_file_exists("/Library/LaunchDaemons/edu.berkeley.boinc.plist") || // New-style daemon uses launchd
|
||||
boinc_file_exists("/Library/StartupItems/boinc/boinc") ) { // Old-style daemon uses StartupItem
|
||||
bReturnValue = true;
|
||||
}
|
||||
#endif
|
||||
return bReturnValue;
|
||||
}
|
||||
|
||||
|
||||
bool CBOINCClientManager::IsBOINCCoreRunning() {
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::IsBOINCCoreRunning - Function Begin"));
|
||||
|
||||
int retval;
|
||||
bool running = false;
|
||||
HOST_INFO hostinfo;
|
||||
RPC_CLIENT rpc;
|
||||
|
||||
#ifdef __WXMSW__
|
||||
if (IsBOINCServiceInstalled()) {
|
||||
running = (FALSE != IsBOINCServiceStarting()) || (FALSE != IsBOINCServiceRunning());
|
||||
} else {
|
||||
#endif
|
||||
// If set up to run as a daemon, allow time for daemon to start up
|
||||
for (int i=0; i<10; i++) {
|
||||
retval = rpc.init("localhost"); // synchronous is OK since local
|
||||
wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::IsBOINCCoreRunning - Connecting to core client returned '%d'"), retval);
|
||||
retval = rpc.get_host_info(hostinfo);
|
||||
wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::IsBOINCCoreRunning - Requesting host info... retval '%d'"), retval);
|
||||
running = (retval == 0);
|
||||
rpc.close();
|
||||
if (running) break;
|
||||
if (!IsBOINCDaemon()) break;
|
||||
wxSleep(1);
|
||||
}
|
||||
#ifdef __WXMSW__
|
||||
}
|
||||
#endif
|
||||
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::IsBOINCCoreRunning - Function End"));
|
||||
return running;
|
||||
}
|
||||
|
||||
|
||||
bool CBOINCClientManager::StartupBOINCCore() {
|
||||
bool bReturnValue = false;
|
||||
|
||||
#ifdef __WXMSW__
|
||||
if (IsBOINCDaemon()) {
|
||||
bReturnValue = (StartBOINCService() == TRUE);
|
||||
}
|
||||
#endif
|
||||
if (!IsBOINCCoreRunning()
|
||||
#ifdef __WXMSW__
|
||||
&& !IsBOINCDaemon()
|
||||
#endif
|
||||
) {
|
||||
wxString strExecute = wxEmptyString;
|
||||
|
||||
#if defined(__WXMSW__)
|
||||
LPTSTR szExecute = NULL;
|
||||
LPTSTR szDataDirectory = NULL;
|
||||
|
||||
// Append boinc.exe to the end of the strExecute string and get ready to rock
|
||||
strExecute.Printf(
|
||||
wxT("\"%s\\boinc.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();
|
||||
}
|
||||
|
||||
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__)
|
||||
|
||||
{
|
||||
wxChar buf[1024];
|
||||
wxChar *argv[5];
|
||||
ProcessSerialNumber ourPSN;
|
||||
FSRef ourFSRef;
|
||||
OSErr err;
|
||||
|
||||
// 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/boinc\" -redirectio -launched_by_manager");
|
||||
m_lBOINCCoreProcessId = ::wxExecute(strExecute);
|
||||
#else // Use wxExecute(wxChar **argv ...) instead of wxExecute(wxString& ...)
|
||||
strcat(buf, "/Contents/Resources/boinc");
|
||||
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/BOINC Data", buf, argv[3] ? 4 : 3, argv, 0.0, m_lBOINCCoreProcessId);
|
||||
#endif
|
||||
} else {
|
||||
buf[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
#else // Unix based systems
|
||||
|
||||
// copy the path to the boinmgr from argv[0]
|
||||
strExecute = wxString((const char*)wxGetApp().argv[0], wxConvUTF8);
|
||||
|
||||
// Append boinc.exe to the end of the strExecute string and get ready to rock
|
||||
strExecute += wxT("/boinc -redirectio -launched_by_manager");
|
||||
if (! g_use_sandbox)
|
||||
strExecute += wxT(" -insecure");
|
||||
m_lBOINCCoreProcessId = ::wxExecute(strExecute);
|
||||
|
||||
#endif
|
||||
|
||||
if (0 != m_lBOINCCoreProcessId) {
|
||||
m_bBOINCStartedByManager = true;
|
||||
bReturnValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
return bReturnValue;
|
||||
}
|
||||
|
||||
|
||||
#if defined(__WXMSW__)
|
||||
|
||||
void CBOINCClientManager::ShutdownBOINCCore() {
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::ShutdownBOINCCore - Function Begin"));
|
||||
|
||||
CMainDocument* pDoc = wxGetApp().GetDocument();
|
||||
wxInt32 iCount = 0;
|
||||
DWORD dwExitCode = 0;
|
||||
bool bClientQuit = false;
|
||||
wxString strConnectedCompter = wxEmptyString;
|
||||
wxString strPassword = wxEmptyString;
|
||||
|
||||
wxASSERT(pDoc);
|
||||
wxASSERT(wxDynamicCast(pDoc, CMainDocument));
|
||||
|
||||
if (m_bBOINCStartedByManager) {
|
||||
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 (GetExitCodeProcess(m_hBOINCCoreProcess, &dwExitCode)) {
|
||||
if (STILL_ACTIVE == dwExitCode) {
|
||||
rpc.quit();
|
||||
for (iCount = 0; iCount <= 10; iCount++) {
|
||||
if (!bClientQuit && GetExitCodeProcess(m_hBOINCCoreProcess, &dwExitCode)) {
|
||||
if (STILL_ACTIVE != dwExitCode) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rpc.close();
|
||||
} else {
|
||||
if (GetExitCodeProcess(m_hBOINCCoreProcess, &dwExitCode)) {
|
||||
if (STILL_ACTIVE == dwExitCode) {
|
||||
pDoc->CoreClientQuit();
|
||||
for (iCount = 0; iCount <= 10; iCount++) {
|
||||
if (!bClientQuit && GetExitCodeProcess(m_hBOINCCoreProcess, &dwExitCode)) {
|
||||
if (STILL_ACTIVE != dwExitCode) {
|
||||
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..."));
|
||||
::wxSleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bClientQuit) {
|
||||
::wxKill(m_lBOINCCoreProcessId);
|
||||
}
|
||||
}
|
||||
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::ShutdownBOINCCore - Function End"));
|
||||
}
|
||||
|
||||
#elif defined(__WXMAC__)
|
||||
|
||||
static char * PersistentFGets(char *buf, size_t buflen, FILE *f) {
|
||||
char *p = buf;
|
||||
size_t len = buflen;
|
||||
size_t datalen = 0;
|
||||
|
||||
*buf = '\0';
|
||||
while (datalen < (buflen - 1)) {
|
||||
fgets(p, len, f);
|
||||
if (feof(f)) break;
|
||||
if (ferror(f) && (errno != EINTR)) break;
|
||||
if (strchr(buf, '\n')) break;
|
||||
datalen = strlen(buf);
|
||||
p = buf + datalen;
|
||||
len -= datalen;
|
||||
}
|
||||
return (buf[0] ? buf : NULL);
|
||||
}
|
||||
|
||||
bool CBOINCClientManager::ProcessExists(pid_t thePID)
|
||||
{
|
||||
FILE *f;
|
||||
char buf[256];
|
||||
pid_t aPID;
|
||||
|
||||
f = popen("ps -a -x -c -o pid,state", "r");
|
||||
if (f == NULL)
|
||||
return false;
|
||||
|
||||
while (PersistentFGets(buf, sizeof(buf), f)) {
|
||||
aPID = atol(buf);
|
||||
if (aPID == thePID) {
|
||||
if (strchr(buf, 'Z')) // A 'zombie', stopped but waiting
|
||||
break; // for us (its parent) to quit
|
||||
pclose(f);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
pclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
// wxProcess::Exists and wxKill are unimplemented in WxMac-2.6.0
|
||||
void CBOINCClientManager::ShutdownBOINCCore() {
|
||||
CMainDocument* pDoc = wxGetApp().GetDocument();
|
||||
wxInt32 iCount = 0;
|
||||
wxString strConnectedCompter = wxEmptyString;
|
||||
wxString strPassword = wxEmptyString;
|
||||
|
||||
wxASSERT(pDoc);
|
||||
wxASSERT(wxDynamicCast(pDoc, CMainDocument));
|
||||
|
||||
if (m_bBOINCStartedByManager) {
|
||||
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 (ProcessExists(m_lBOINCCoreProcessId)) {
|
||||
rpc.quit();
|
||||
for (iCount = 0; iCount <= 10; iCount++) {
|
||||
if (!ProcessExists(m_lBOINCCoreProcessId))
|
||||
return;
|
||||
::wxSleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
rpc.close();
|
||||
} else {
|
||||
if (ProcessExists(m_lBOINCCoreProcessId)) {
|
||||
pDoc->CoreClientQuit();
|
||||
for (iCount = 0; iCount <= 10; iCount++) {
|
||||
if (!ProcessExists(m_lBOINCCoreProcessId))
|
||||
return;
|
||||
|
||||
::wxSleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Client did not quit after 10 seconds so kill it
|
||||
kill(m_lBOINCCoreProcessId, SIGKILL);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void CBOINCClientManager::ShutdownBOINCCore() {
|
||||
CMainDocument* pDoc = wxGetApp().GetDocument();
|
||||
wxInt32 iCount = 0;
|
||||
bool bClientQuit = false;
|
||||
wxString strConnectedCompter = wxEmptyString;
|
||||
wxString strPassword = wxEmptyString;
|
||||
|
||||
wxASSERT(pDoc);
|
||||
wxASSERT(wxDynamicCast(pDoc, CMainDocument));
|
||||
|
||||
if (m_bBOINCStartedByManager) {
|
||||
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 (wxProcess::Exists(m_lBOINCCoreProcessId)) {
|
||||
rpc.quit();
|
||||
for (iCount = 0; iCount <= 10; iCount++) {
|
||||
if (!bClientQuit && !wxProcess::Exists(m_lBOINCCoreProcessId)) {
|
||||
bClientQuit = true;
|
||||
break;
|
||||
}
|
||||
::wxSleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
rpc.close();
|
||||
} else {
|
||||
if (wxProcess::Exists(m_lBOINCCoreProcessId)) {
|
||||
pDoc->CoreClientQuit();
|
||||
for (iCount = 0; iCount <= 10; iCount++) {
|
||||
if (!bClientQuit && !wxProcess::Exists(m_lBOINCCoreProcessId)) {
|
||||
bClientQuit = true;
|
||||
break;
|
||||
}
|
||||
::wxSleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bClientQuit) {
|
||||
::wxKill(m_lBOINCCoreProcessId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
// Berkeley Open Infrastructure for Network Computing
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2005 University of California
|
||||
//
|
||||
// This is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation;
|
||||
// either version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This software is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// To view the GNU Lesser General Public License visit
|
||||
// http://www.gnu.org/copyleft/lesser.html
|
||||
// or write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#ifndef _BOINCCLIENTMANAGER_H_
|
||||
#define _BOINCCLIENTMANAGER_H_
|
||||
|
||||
#if defined(__GNUG__) && !defined(__APPLE__)
|
||||
#pragma interface "BOINCClientManager.cpp"
|
||||
#endif
|
||||
|
||||
|
||||
class CBOINCClientManager : public wxObject
|
||||
{
|
||||
public:
|
||||
|
||||
CBOINCClientManager();
|
||||
~CBOINCClientManager();
|
||||
|
||||
bool AutoRestart();
|
||||
|
||||
bool IsSystemBooting();
|
||||
bool IsBOINCDaemon();
|
||||
|
||||
bool IsBOINCCoreRunning();
|
||||
bool StartupBOINCCore();
|
||||
void ShutdownBOINCCore();
|
||||
#ifdef __WXMAC__
|
||||
bool ProcessExists(pid_t thePID);
|
||||
static OSErr QuitAppleEventHandler( const AppleEvent *appleEvt, AppleEvent* reply, UInt32 refcon );
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
bool m_bBOINCStartedByManager;
|
||||
bool m_bClientRunningAsDaemon;
|
||||
int m_lBOINCCoreProcessId;
|
||||
|
||||
#ifdef __WXMSW__
|
||||
HANDLE m_hBOINCCoreProcess;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -44,6 +44,7 @@
|
|||
#include "BOINCGUIApp.h"
|
||||
#include "SkinManager.h"
|
||||
#include "MainDocument.h"
|
||||
#include "BOINCClientManager.h"
|
||||
#include "BOINCTaskBar.h"
|
||||
#include "BOINCBaseFrame.h"
|
||||
#include "AdvancedFrame.h"
|
||||
|
@ -55,20 +56,12 @@
|
|||
static bool s_bSkipExitConfirmation = false;
|
||||
|
||||
#ifdef __WXMSW__
|
||||
EXTERN_C BOOL IsBOINCServiceInstalled();
|
||||
EXTERN_C BOOL IsBOINCServiceStarting();
|
||||
EXTERN_C BOOL IsBOINCServiceRunning();
|
||||
EXTERN_C BOOL IsBOINCServiceStopping();
|
||||
EXTERN_C BOOL IsBOINCServiceStopped();
|
||||
EXTERN_C BOOL StartBOINCService();
|
||||
EXTERN_C BOOL StopBOINCService();
|
||||
EXTERN_C BOOL ClientLibraryStartup();
|
||||
EXTERN_C void ClientLibraryShutdown();
|
||||
EXTERN_C int BOINCIsNetworkAlive(long* lpdwFlags);
|
||||
EXTERN_C int BOINCIsNetworkAlwaysOnline();
|
||||
EXTERN_C DWORD BOINCGetIdleTickCount();
|
||||
#endif
|
||||
|
||||
|
||||
IMPLEMENT_APP(CBOINCGUIApp)
|
||||
IMPLEMENT_DYNAMIC_CLASS(CBOINCGUIApp, wxApp)
|
||||
|
||||
|
@ -76,7 +69,6 @@ IMPLEMENT_DYNAMIC_CLASS(CBOINCGUIApp, wxApp)
|
|||
bool CBOINCGUIApp::OnInit() {
|
||||
|
||||
// Setup variables with default values
|
||||
m_bBOINCStartedByManager = false;
|
||||
m_strBOINCArguments = wxEmptyString;
|
||||
m_strBOINCMGRRootDirectory = wxEmptyString;
|
||||
m_pLocale = NULL;
|
||||
|
@ -86,17 +78,14 @@ bool CBOINCGUIApp::OnInit() {
|
|||
m_pTaskBarIcon = NULL;
|
||||
#ifdef __WXMAC__
|
||||
m_pMacSystemMenu = NULL;
|
||||
m_bClientRunningAsDaemon = false;
|
||||
printf("Using %s.\n", wxVERSION_STRING); // For debugging
|
||||
#endif
|
||||
m_bGUIVisible = true;
|
||||
m_strDefaultWindowStation = wxEmptyString;
|
||||
m_strDefaultDesktop = wxEmptyString;
|
||||
m_strDefaultDisplay = wxEmptyString;
|
||||
m_lBOINCCoreProcessId = 0;
|
||||
m_iGUISelected = BOINC_SIMPLEGUI;
|
||||
#ifdef __WXMSW__
|
||||
m_hBOINCCoreProcess = NULL;
|
||||
m_hClientLibraryDll = NULL;
|
||||
#endif
|
||||
|
||||
|
@ -358,16 +347,6 @@ bool CBOINCGUIApp::OnInit() {
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef __WXMAC__
|
||||
// When running BOINC Client as a daemon / service, the menubar icon is sometimes
|
||||
// unresponsive to mouse clicks if we create it before connecting to the Client.
|
||||
bool m_bClientRunningAsDaemon = (TickCount() < (120*60)) && // If system has been up for less than 2 minutes
|
||||
( boinc_file_exists("/Library/LaunchDaemons/edu.berkeley.boinc.plist") || // New-style daemon uses launchd
|
||||
boinc_file_exists("/Library/StartupItems/boinc/boinc") ); // Old-style daemon uses StartupItem
|
||||
|
||||
if (m_bClientRunningAsDaemon) StartupBOINCCore();
|
||||
#endif
|
||||
|
||||
// Initialize the task bar icon
|
||||
#if defined(__WXMSW__) || defined(__WXMAC__)
|
||||
m_pTaskBarIcon = new CTaskBarIcon(
|
||||
|
@ -385,11 +364,6 @@ bool CBOINCGUIApp::OnInit() {
|
|||
// Startup the System Idle Detection code
|
||||
ClientLibraryStartup();
|
||||
|
||||
#ifdef __WXMAC__
|
||||
if (! m_bClientRunningAsDaemon)
|
||||
#endif
|
||||
StartupBOINCCore();
|
||||
|
||||
#ifdef __WXMAC__
|
||||
s_bSkipExitConfirmation = false;
|
||||
AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP((AEEventHandlerProcPtr)QuitAppleEventHandler), 0, false );
|
||||
|
@ -442,9 +416,6 @@ bool CBOINCGUIApp::OnInit() {
|
|||
|
||||
|
||||
int CBOINCGUIApp::OnExit() {
|
||||
// Detect if we need to stop the BOINC Core Client due to configuration
|
||||
ShutdownBOINCCore();
|
||||
|
||||
// Shutdown the System Idle Detection code
|
||||
ClientLibraryShutdown();
|
||||
|
||||
|
@ -548,320 +519,7 @@ void CBOINCGUIApp::InitSupportedLanguages() {
|
|||
}
|
||||
|
||||
|
||||
bool CBOINCGUIApp::AutoRestartBOINC() {
|
||||
if (!IsBOINCCoreRunning() && m_bBOINCStartedByManager) {
|
||||
StartupBOINCCore();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CBOINCGUIApp::IsBOINCCoreRunning() {
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCGUIApp::IsBOINCCoreRunning - Function Begin"));
|
||||
|
||||
int retval;
|
||||
bool running = false;
|
||||
HOST_INFO hostinfo;
|
||||
RPC_CLIENT rpc;
|
||||
|
||||
#ifdef __WXMSW__
|
||||
|
||||
if (IsBOINCServiceInstalled()) {
|
||||
running = (FALSE != IsBOINCServiceStarting()) || (FALSE != IsBOINCServiceRunning());
|
||||
} else {
|
||||
retval = rpc.init("localhost"); // synchronous is OK since local
|
||||
wxLogTrace(wxT("Function Status"), wxT("CBOINCGUIApp::IsBOINCCoreRunning - Connecting to core client returned '%d'"), retval);
|
||||
retval = rpc.get_host_info(hostinfo);
|
||||
wxLogTrace(wxT("Function Status"), wxT("CBOINCGUIApp::IsBOINCCoreRunning - Requesting host info... retval '%d'"), retval);
|
||||
running = (retval == 0);
|
||||
rpc.close();
|
||||
}
|
||||
|
||||
#elif defined __WXMAC__
|
||||
// If set up to run as a daemon, allow time for daemon to start up
|
||||
for (int i=0; i<10; i++) {
|
||||
retval = rpc.init("localhost"); // synchronous is OK since local
|
||||
retval = rpc.get_host_info(hostinfo);
|
||||
running = (retval == 0);
|
||||
rpc.close();
|
||||
if (running) break;
|
||||
if (! m_bClientRunningAsDaemon) break;
|
||||
sleep(1);
|
||||
}
|
||||
#else
|
||||
retval = rpc.init("localhost"); // synchronous is OK since local
|
||||
retval = rpc.get_host_info(hostinfo);
|
||||
running = (retval == 0);
|
||||
rpc.close();
|
||||
#endif
|
||||
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCGUIApp::IsBOINCCoreRunning - Function End"));
|
||||
return running;
|
||||
}
|
||||
|
||||
|
||||
void CBOINCGUIApp::StartupBOINCCore() {
|
||||
if (!IsBOINCCoreRunning()) {
|
||||
wxString strExecute = wxEmptyString;
|
||||
|
||||
#if defined(__WXMSW__)
|
||||
LPTSTR szExecute = NULL;
|
||||
LPTSTR szDataDirectory = NULL;
|
||||
|
||||
// Append boinc.exe to the end of the strExecute string and get ready to rock
|
||||
strExecute.Printf(
|
||||
wxT("\"%s\\boinc.exe\" -redirectio -launched_by_manager %s"),
|
||||
GetRootDirectory().c_str(),
|
||||
m_strBOINCArguments.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 (GetDataDirectory().empty()) {
|
||||
szDataDirectory = NULL;
|
||||
} else {
|
||||
szDataDirectory = (LPTSTR)GetDataDirectory().c_str();
|
||||
}
|
||||
|
||||
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__)
|
||||
|
||||
{
|
||||
wxChar buf[1024];
|
||||
wxChar *argv[5];
|
||||
ProcessSerialNumber ourPSN;
|
||||
FSRef ourFSRef;
|
||||
OSErr err;
|
||||
|
||||
// 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/boinc\" -redirectio -launched_by_manager");
|
||||
m_lBOINCCoreProcessId = ::wxExecute(strExecute);
|
||||
#else // Use wxExecute(wxChar **argv ...) instead of wxExecute(wxString& ...)
|
||||
strcat(buf, "/Contents/Resources/boinc");
|
||||
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/BOINC Data", buf, argv[3] ? 4 : 3, argv, 0.0, m_lBOINCCoreProcessId);
|
||||
#endif
|
||||
} else {
|
||||
buf[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
#else // Unix based systems
|
||||
|
||||
// copy the path to the boinmgr from argv[0]
|
||||
strExecute = wxString((const char*)wxGetApp().argv[0], wxConvUTF8);
|
||||
|
||||
// Append boinc.exe to the end of the strExecute string and get ready to rock
|
||||
strExecute += wxT("/boinc -redirectio -launched_by_manager");
|
||||
if (! g_use_sandbox)
|
||||
strExecute += wxT(" -insecure");
|
||||
m_lBOINCCoreProcessId = ::wxExecute(strExecute);
|
||||
|
||||
#endif
|
||||
|
||||
if (0 != m_lBOINCCoreProcessId) {
|
||||
m_bBOINCStartedByManager = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(__WXMSW__)
|
||||
|
||||
void CBOINCGUIApp::ShutdownBOINCCore() {
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCGUIApp::ShutdownBOINCCore - Function Begin"));
|
||||
|
||||
wxInt32 iCount = 0;
|
||||
DWORD dwExitCode = 0;
|
||||
bool bClientQuit = false;
|
||||
wxString strConnectedCompter = wxEmptyString;
|
||||
wxString strPassword = wxEmptyString;
|
||||
|
||||
if (m_bBOINCStartedByManager) {
|
||||
m_pDocument->GetConnectedComputerName(strConnectedCompter);
|
||||
if (!m_pDocument->IsComputerNameLocal(strConnectedCompter)) {
|
||||
RPC_CLIENT rpc;
|
||||
if (!rpc.init("localhost")) {
|
||||
m_pDocument->m_pNetworkConnection->GetLocalPassword(strPassword);
|
||||
rpc.authorize((const char*)strPassword.mb_str());
|
||||
if (GetExitCodeProcess(m_hBOINCCoreProcess, &dwExitCode)) {
|
||||
if (STILL_ACTIVE == dwExitCode) {
|
||||
rpc.quit();
|
||||
for (iCount = 0; iCount <= 10; iCount++) {
|
||||
if (!bClientQuit && GetExitCodeProcess(m_hBOINCCoreProcess, &dwExitCode)) {
|
||||
if (STILL_ACTIVE != dwExitCode) {
|
||||
wxLogTrace(wxT("Function Status"), wxT("CBOINCGUIApp::ShutdownBOINCCore - (localhost) Application Exit Detected"));
|
||||
bClientQuit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
wxLogTrace(wxT("Function Status"), wxT("CBOINCGUIApp::ShutdownBOINCCore - (localhost) Application Exit NOT Detected, Sleeping..."));
|
||||
::wxSleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rpc.close();
|
||||
} else {
|
||||
if (GetExitCodeProcess(m_hBOINCCoreProcess, &dwExitCode)) {
|
||||
if (STILL_ACTIVE == dwExitCode) {
|
||||
m_pDocument->CoreClientQuit();
|
||||
for (iCount = 0; iCount <= 10; iCount++) {
|
||||
if (!bClientQuit && GetExitCodeProcess(m_hBOINCCoreProcess, &dwExitCode)) {
|
||||
if (STILL_ACTIVE != dwExitCode) {
|
||||
wxLogTrace(wxT("Function Status"), wxT("CBOINCGUIApp::ShutdownBOINCCore - Application Exit Detected"));
|
||||
bClientQuit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
wxLogTrace(wxT("Function Status"), wxT("CBOINCGUIApp::ShutdownBOINCCore - Application Exit NOT Detected, Sleeping..."));
|
||||
::wxSleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bClientQuit) {
|
||||
::wxKill(m_lBOINCCoreProcessId);
|
||||
}
|
||||
}
|
||||
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCGUIApp::ShutdownBOINCCore - Function End"));
|
||||
}
|
||||
|
||||
#elif defined(__WXMAC__)
|
||||
|
||||
static char * PersistentFGets(char *buf, size_t buflen, FILE *f) {
|
||||
char *p = buf;
|
||||
size_t len = buflen;
|
||||
size_t datalen = 0;
|
||||
|
||||
*buf = '\0';
|
||||
while (datalen < (buflen - 1)) {
|
||||
fgets(p, len, f);
|
||||
if (feof(f)) break;
|
||||
if (ferror(f) && (errno != EINTR)) break;
|
||||
if (strchr(buf, '\n')) break;
|
||||
datalen = strlen(buf);
|
||||
p = buf + datalen;
|
||||
len -= datalen;
|
||||
}
|
||||
return (buf[0] ? buf : NULL);
|
||||
}
|
||||
|
||||
bool CBOINCGUIApp::ProcessExists(pid_t thePID)
|
||||
{
|
||||
FILE *f;
|
||||
char buf[256];
|
||||
pid_t aPID;
|
||||
|
||||
f = popen("ps -a -x -c -o pid,state", "r");
|
||||
if (f == NULL)
|
||||
return false;
|
||||
|
||||
while (PersistentFGets(buf, sizeof(buf), f)) {
|
||||
aPID = atol(buf);
|
||||
if (aPID == thePID) {
|
||||
if (strchr(buf, 'Z')) // A 'zombie', stopped but waiting
|
||||
break; // for us (its parent) to quit
|
||||
pclose(f);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
pclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
// wxProcess::Exists and wxKill are unimplemented in WxMac-2.6.0
|
||||
void CBOINCGUIApp::ShutdownBOINCCore() {
|
||||
wxInt32 iCount = 0;
|
||||
wxString strConnectedCompter = wxEmptyString;
|
||||
wxString strPassword = wxEmptyString;
|
||||
|
||||
if (m_bBOINCStartedByManager) {
|
||||
m_pDocument->GetConnectedComputerName(strConnectedCompter);
|
||||
if (!m_pDocument->IsComputerNameLocal(strConnectedCompter)) {
|
||||
RPC_CLIENT rpc;
|
||||
if (!rpc.init("localhost")) {
|
||||
m_pDocument->m_pNetworkConnection->GetLocalPassword(strPassword);
|
||||
rpc.authorize((const char*)strPassword.mb_str());
|
||||
if (ProcessExists(m_lBOINCCoreProcessId)) {
|
||||
rpc.quit();
|
||||
for (iCount = 0; iCount <= 10; iCount++) {
|
||||
if (!ProcessExists(m_lBOINCCoreProcessId))
|
||||
return;
|
||||
::wxSleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
rpc.close();
|
||||
} else {
|
||||
if (ProcessExists(m_lBOINCCoreProcessId)) {
|
||||
m_pDocument->CoreClientQuit();
|
||||
for (iCount = 0; iCount <= 10; iCount++) {
|
||||
if (!ProcessExists(m_lBOINCCoreProcessId))
|
||||
return;
|
||||
|
||||
::wxSleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Client did not quit after 10 seconds so kill it
|
||||
kill(m_lBOINCCoreProcessId, SIGKILL);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __WXMAC__
|
||||
|
||||
// Set s_bSkipExitConfirmation to true if cancelled because of logging out or shutting down
|
||||
OSErr CBOINCGUIApp::QuitAppleEventHandler( const AppleEvent *appleEvt, AppleEvent* reply, UInt32 refcon ) {
|
||||
|
@ -911,52 +569,6 @@ OSErr CBOINCGUIApp::QuitAppleEventHandler( const AppleEvent *appleEvt, AppleEven
|
|||
return wxGetApp().MacHandleAEQuit((AppleEvent*)appleEvt, reply);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void CBOINCGUIApp::ShutdownBOINCCore() {
|
||||
wxInt32 iCount = 0;
|
||||
bool bClientQuit = false;
|
||||
wxString strConnectedCompter = wxEmptyString;
|
||||
wxString strPassword = wxEmptyString;
|
||||
|
||||
if (m_bBOINCStartedByManager) {
|
||||
m_pDocument->GetConnectedComputerName(strConnectedCompter);
|
||||
if (!m_pDocument->IsComputerNameLocal(strConnectedCompter)) {
|
||||
RPC_CLIENT rpc;
|
||||
if (!rpc.init("localhost")) {
|
||||
m_pDocument->m_pNetworkConnection->GetLocalPassword(strPassword);
|
||||
rpc.authorize((const char*)strPassword.mb_str());
|
||||
if (wxProcess::Exists(m_lBOINCCoreProcessId)) {
|
||||
rpc.quit();
|
||||
for (iCount = 0; iCount <= 10; iCount++) {
|
||||
if (!bClientQuit && !wxProcess::Exists(m_lBOINCCoreProcessId)) {
|
||||
bClientQuit = true;
|
||||
break;
|
||||
}
|
||||
::wxSleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
rpc.close();
|
||||
} else {
|
||||
if (wxProcess::Exists(m_lBOINCCoreProcessId)) {
|
||||
m_pDocument->CoreClientQuit();
|
||||
for (iCount = 0; iCount <= 10; iCount++) {
|
||||
if (!bClientQuit && !wxProcess::Exists(m_lBOINCCoreProcessId)) {
|
||||
bClientQuit = true;
|
||||
break;
|
||||
}
|
||||
::wxSleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bClientQuit) {
|
||||
::wxKill(m_lBOINCCoreProcessId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -1068,12 +680,15 @@ bool CBOINCGUIApp::SetActiveGUI(int iGUISelection, bool bShowWindow) {
|
|||
|
||||
int CBOINCGUIApp::ConfirmExit() {
|
||||
CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced();
|
||||
CMainDocument* pDoc = wxGetApp().GetDocument();
|
||||
wxString strTitle;
|
||||
|
||||
|
||||
wxASSERT(pDoc);
|
||||
wxASSERT(pSkinAdvanced);
|
||||
wxASSERT(wxDynamicCast(pDoc, CMainDocument));
|
||||
wxASSERT(wxDynamicCast(pSkinAdvanced, CSkinAdvanced));
|
||||
|
||||
if (!m_bBOINCStartedByManager)
|
||||
if (pDoc->m_pClientManager->IsBOINCDaemon())
|
||||
return 1; // Don't run dialog if exiting manager won't shut down Client or its tasks
|
||||
|
||||
if (!m_iDisplayExitWarning)
|
||||
|
|
|
@ -52,11 +52,7 @@ protected:
|
|||
|
||||
void InitSupportedLanguages();
|
||||
|
||||
bool IsBOINCCoreRunning();
|
||||
void StartupBOINCCore();
|
||||
void ShutdownBOINCCore();
|
||||
#ifdef __WXMAC__
|
||||
bool ProcessExists(pid_t thePID);
|
||||
static OSErr QuitAppleEventHandler( const AppleEvent *appleEvt, AppleEvent* reply, UInt32 refcon );
|
||||
#endif
|
||||
|
||||
|
@ -73,10 +69,8 @@ protected:
|
|||
CTaskBarIcon* m_pTaskBarIcon;
|
||||
#ifdef __WXMAC__
|
||||
CMacSystemMenu* m_pMacSystemMenu;
|
||||
bool m_bClientRunningAsDaemon;
|
||||
#endif
|
||||
|
||||
bool m_bBOINCStartedByManager;
|
||||
wxString m_strBOINCMGRRootDirectory;
|
||||
wxString m_strBOINCMGRDataDirectory;
|
||||
wxString m_strBOINCArguments;
|
||||
|
@ -86,10 +80,7 @@ protected:
|
|||
bool m_bGUIVisible;
|
||||
int m_iGUISelected;
|
||||
|
||||
int m_lBOINCCoreProcessId;
|
||||
|
||||
#ifdef __WXMSW__
|
||||
HANDLE m_hBOINCCoreProcess;
|
||||
HINSTANCE m_hClientLibraryDll;
|
||||
#endif
|
||||
|
||||
|
@ -105,8 +96,6 @@ public:
|
|||
|
||||
bool OnInit();
|
||||
|
||||
bool AutoRestartBOINC();
|
||||
|
||||
int UpdateSystemIdleDetection();
|
||||
|
||||
int StartBOINCScreensaverTest();
|
||||
|
@ -115,6 +104,7 @@ public:
|
|||
CSkinManager* GetSkinManager() { return m_pSkinManager; }
|
||||
CBOINCBaseFrame* GetFrame() { return m_pFrame; }
|
||||
CMainDocument* GetDocument() { return m_pDocument; }
|
||||
wxString GetArguments() { return m_strBOINCArguments; }
|
||||
wxString GetRootDirectory() { return m_strBOINCMGRRootDirectory; }
|
||||
wxString GetDataDirectory() { return m_strBOINCMGRDataDirectory; }
|
||||
#if defined(__WXMSW__) || defined(__WXMAC__)
|
||||
|
|
|
@ -29,8 +29,9 @@
|
|||
#include "BOINCGUIApp.h"
|
||||
#include "BOINCBaseFrame.h"
|
||||
#include "MainDocument.h"
|
||||
#ifdef _WIN32
|
||||
#else
|
||||
#include "BOINCClientManager.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
|
@ -313,6 +314,7 @@ IMPLEMENT_DYNAMIC_CLASS(CMainDocument, wxObject)
|
|||
|
||||
|
||||
CMainDocument::CMainDocument() {
|
||||
|
||||
#ifdef __WIN32__
|
||||
int retval;
|
||||
WSADATA wsdata;
|
||||
|
@ -323,6 +325,8 @@ CMainDocument::CMainDocument() {
|
|||
}
|
||||
#endif
|
||||
|
||||
m_bClientStartCheckCompleted = false;
|
||||
|
||||
m_fProjectTotalResourceShare = 0.0;
|
||||
|
||||
m_iMessageSequenceNumber = 0;
|
||||
|
@ -347,6 +351,86 @@ CMainDocument::~CMainDocument() {
|
|||
}
|
||||
|
||||
|
||||
int CMainDocument::OnInit() {
|
||||
int iRetVal = -1;
|
||||
|
||||
m_pNetworkConnection = new CNetworkConnection(this);
|
||||
wxASSERT(m_pNetworkConnection);
|
||||
|
||||
m_pClientManager = new CBOINCClientManager();
|
||||
wxASSERT(m_pClientManager);
|
||||
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
|
||||
int CMainDocument::OnExit() {
|
||||
int iRetVal = 0;
|
||||
|
||||
if (m_pClientManager) {
|
||||
m_pClientManager->ShutdownBOINCCore();
|
||||
|
||||
delete m_pClientManager;
|
||||
m_pClientManager = NULL;
|
||||
}
|
||||
|
||||
if (m_pNetworkConnection) {
|
||||
delete m_pNetworkConnection;
|
||||
m_pNetworkConnection = NULL;
|
||||
}
|
||||
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
|
||||
int CMainDocument::OnPoll() {
|
||||
int iRetVal = 0;
|
||||
|
||||
wxASSERT(wxDynamicCast(m_pClientManager, CBOINCClientManager));
|
||||
wxASSERT(wxDynamicCast(m_pNetworkConnection, CNetworkConnection));
|
||||
|
||||
if (!m_bClientStartCheckCompleted) {
|
||||
m_bClientStartCheckCompleted = true;
|
||||
|
||||
CBOINCBaseFrame* pFrame = wxGetApp().GetFrame();
|
||||
wxASSERT(wxDynamicCast(pFrame, CBOINCBaseFrame));
|
||||
|
||||
pFrame->UpdateStatusText(_("Starting client services; please wait..."));
|
||||
|
||||
if (m_pClientManager->StartupBOINCCore()) {
|
||||
Connect(wxT("localhost"), wxEmptyString, TRUE, TRUE);
|
||||
} else {
|
||||
m_pNetworkConnection->ForceDisconnect();
|
||||
pFrame->ShowDaemonStartFailedAlert();
|
||||
}
|
||||
|
||||
pFrame->UpdateStatusText(wxEmptyString);
|
||||
}
|
||||
|
||||
// Check connection state, connect if needed.
|
||||
m_pNetworkConnection->Poll();
|
||||
|
||||
// Every 10 seconds, kill any running graphics apps
|
||||
// whose associated worker tasks are no longer running
|
||||
wxTimeSpan ts(wxDateTime::Now() - m_dtKillInactiveGfxTimestamp);
|
||||
if (ts.GetSeconds() > 10) {
|
||||
m_dtKillInactiveGfxTimestamp = wxDateTime::Now();
|
||||
KillInactiveGraphicsApps();
|
||||
}
|
||||
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
|
||||
int CMainDocument::OnRefreshState() {
|
||||
if (IsConnected()) {
|
||||
CachedStateUpdate();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CMainDocument::CachedStateUpdate() {
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CMainDocument::CachedStateUpdate - Function Begin"));
|
||||
|
||||
|
@ -380,56 +464,6 @@ int CMainDocument::CachedStateUpdate() {
|
|||
}
|
||||
|
||||
|
||||
int CMainDocument::OnInit() {
|
||||
int iRetVal = -1;
|
||||
|
||||
// start the connect management thread
|
||||
m_pNetworkConnection = new CNetworkConnection(this);
|
||||
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
|
||||
int CMainDocument::OnExit() {
|
||||
int iRetVal = 0;
|
||||
|
||||
if (m_pNetworkConnection) {
|
||||
delete m_pNetworkConnection;
|
||||
m_pNetworkConnection = NULL;
|
||||
}
|
||||
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
|
||||
int CMainDocument::OnPoll() {
|
||||
int iRetVal = 0;
|
||||
|
||||
if (m_pNetworkConnection) {
|
||||
m_pNetworkConnection->Poll();
|
||||
}
|
||||
|
||||
// Every 10 seconds, kill any running graphics apps
|
||||
// whose associated worker tasks are no longer running
|
||||
wxTimeSpan ts(wxDateTime::Now() - m_dtKillInactiveGfxTimestamp);
|
||||
if (ts.GetSeconds() > 10) {
|
||||
m_dtKillInactiveGfxTimestamp = wxDateTime::Now();
|
||||
KillInactiveGraphicsApps();
|
||||
}
|
||||
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
|
||||
int CMainDocument::OnRefreshState() {
|
||||
if (IsConnected()) {
|
||||
CachedStateUpdate();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CMainDocument::ResetState() {
|
||||
rpc.close();
|
||||
state.clear();
|
||||
|
@ -1083,7 +1117,7 @@ void CMainDocument::KillInactiveGraphicsApps()
|
|||
|
||||
void CMainDocument::KillAllRunningGraphicsApps()
|
||||
{
|
||||
int i, n;
|
||||
size_t i, n;
|
||||
std::vector<RUNNING_GFX_APP>::iterator gfx_app_iter;
|
||||
|
||||
n = m_running_gfx_apps.size();
|
||||
|
@ -1238,7 +1272,7 @@ int CMainDocument::CachedMessageUpdate() {
|
|||
goto done;
|
||||
}
|
||||
if (messages.messages.size() != 0) {
|
||||
int last_ind = messages.messages.size()-1;
|
||||
size_t last_ind = messages.messages.size()-1;
|
||||
m_iMessageSequenceNumber = messages.messages[last_ind]->seqno;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -43,6 +43,7 @@ typedef struct {
|
|||
extern bool g_use_sandbox;
|
||||
|
||||
class CMainDocument;
|
||||
class CBOINCClientManager;
|
||||
|
||||
class CNetworkConnection : public wxObject {
|
||||
public:
|
||||
|
@ -51,6 +52,7 @@ public:
|
|||
|
||||
void Poll();
|
||||
void FireReconnectEvent() { m_bConnectEvent = true; };
|
||||
void ForceDisconnect() { m_bForceReconnect = false; m_bReconnectOnError = false; m_bConnectEvent = false; SetStateDisconnected(); };
|
||||
void ForceReconnect() { m_bForceReconnect = true; SetStateDisconnected(); };
|
||||
int FrameShutdownDetected();
|
||||
int GetConnectedComputerName(wxString& strMachine);
|
||||
|
@ -101,18 +103,16 @@ public:
|
|||
private:
|
||||
|
||||
wxDateTime m_dtCachedCCStatusTimestamp;
|
||||
bool m_bClientStartCheckCompleted;
|
||||
|
||||
|
||||
public:
|
||||
int CachedStateUpdate();
|
||||
|
||||
CNetworkConnection* m_pNetworkConnection;
|
||||
|
||||
int OnInit();
|
||||
int OnExit();
|
||||
int OnPoll();
|
||||
|
||||
int OnRefreshState();
|
||||
int CachedStateUpdate();
|
||||
int ResetState();
|
||||
|
||||
int Connect(
|
||||
|
@ -145,6 +145,8 @@ public:
|
|||
|
||||
bool IsUserAuthorized();
|
||||
|
||||
CNetworkConnection* m_pNetworkConnection;
|
||||
CBOINCClientManager* m_pClientManager;
|
||||
RPC_CLIENT rpc;
|
||||
CC_STATE state;
|
||||
CC_STATUS status;
|
||||
|
|
|
@ -307,7 +307,7 @@ int run_program(
|
|||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
IDLE_PRIORITY_CLASS,
|
||||
0,
|
||||
NULL,
|
||||
dir,
|
||||
&startup_info,
|
||||
|
|
|
@ -1914,6 +1914,14 @@
|
|||
RelativePath="..\clientgui\BOINCBaseFrame.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\clientgui\BOINCClientManager.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\clientgui\BOINCClientManager.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\clientgui\BOINCDialupManager.cpp"
|
||||
>
|
||||
|
|
Loading…
Reference in New Issue