Skip to content

Commit

Permalink
*** empty log message ***
Browse files Browse the repository at this point in the history
svn path=/trunk/boinc/; revision=11683
  • Loading branch information
davidpanderson committed Dec 14, 2006
1 parent 4bdfe86 commit 46695c2
Show file tree
Hide file tree
Showing 12 changed files with 196 additions and 37 deletions.
31 changes: 31 additions & 0 deletions checkin_notes
Original file line number Diff line number Diff line change
Expand Up @@ -13435,3 +13435,34 @@ David 14 Dec 2006
boinc_ss.vcproj
boincmgr_curl.vcproj
libboinc.vcproj

David 14 Dec 2006
Further work on auto-update:
- add synchronization so that the core client,
when it's ready to do an auto-update,
arranges for any local Manager and screensaver to exit first.
This is done in a slighly kludgy way:
any GUI RPC connection that has done a get_screensaver_mode()
is assumed to be a screensaver,
and we send it a SS_STATUS_QUIT on its next request.
Any connection that has done a get_cc_status() is assumed to
be a Manager, and we set <manager_must_quit> on the next request.
The core client waits until these have been sent,
and waits an additional 10 seconds to let the other program exit.
- updater: add a mandatory --install_dir argument (don't assume ../../..)
- wait_client_mutex(): add a directory argument;
the updater needs to acquire the mutex while it's
running in a different directory
- FILE_LOCK: don't use lots of file descriptors if called repeatedly
- util.C: add boinc_getcwd()

client/
auto_update.C
gui_rpc_server.C,h
gui_rpc_server_ops.C
main.C
lib/
filesys.C,h
util.C
tools/
updater.C
44 changes: 36 additions & 8 deletions client/auto_update.C
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ void AUTO_UPDATE::install() {
unsigned int i;
FILE_INFO* fip=0;
char version_dir[1024];
char cwd[256];
char* argv[10];
int argc;

Expand All @@ -162,27 +163,54 @@ void AUTO_UPDATE::install() {
return;
}
boinc_version_dir(*project, version, version_dir);
boinc_getcwd(cwd);
argv[0] = fip->name;
argv[1] = "--run_core";
argv[2] = 0;
argc = 2;
argv[1] = "--install_dir";
argv[2] = cwd;
argv[3] = "--run_core";
argv[4] = 0;
argc = 4;
run_program(version_dir, fip->name, argc, argv);
gstate.requested_exit = true;
}

// When an update is ready to install, we may need to wait a little:
// 1) If there's a GUI RPC connection from a local screensaver
// (i.e. that has done a get_screensaver_mode())
// wait for the next get_screensaver_mode() and send it SS_STATUS_QUIT
// 2) If there's a GUI RPC connection from a GUI
// (i.e. that has done a get_cc_status())
// wait for the next get_cc_status() and return manager_must_quit = true.
// Wait an additional 10 seconds in any case

void AUTO_UPDATE::poll() {
if (!present) return;
static double last_time = 0;
static bool ready_to_install = false;
static double quits_sent = 0;

if (gstate.now - last_time < 10) return;
last_time = gstate.now;

for (unsigned int i=0; i<file_refs.size(); i++) {
FILE_REF& fref = file_refs[i];
FILE_INFO* fip = fref.file_info;
if (fip->status != FILE_PRESENT) return;
if (ready_to_install) {
if (quits_sent) {
if (gstate.now - quits_sent >= 10) {
install();
}
} else {
if (gstate.gui_rpcs.quits_sent()) {
quits_sent = gstate.now;
}
}
} else {
for (unsigned int i=0; i<file_refs.size(); i++) {
FILE_REF& fref = file_refs[i];
FILE_INFO* fip = fref.file_info;
if (fip->status != FILE_PRESENT) return;
}
ready_to_install = true;
gstate.gui_rpcs.send_quits();
}
install();
}

int VERSION_INFO::parse(MIOFILE& in) {
Expand Down
28 changes: 28 additions & 0 deletions client/gui_rpc_server.C
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ using std::vector;
GUI_RPC_CONN::GUI_RPC_CONN(int s) {
sock = s;
auth_needed = false;
au_ss_state = AU_SS_INIT;
au_mgr_state = AU_MGR_INIT;
}

GUI_RPC_CONN::~GUI_RPC_CONN() {
Expand Down Expand Up @@ -388,4 +390,30 @@ void GUI_RPC_CONN_SET::close() {
}
}

// this is called when we're ready to auto-update;
// set flags to send quit messages to screensaver and local manager
//
void GUI_RPC_CONN_SET::send_quits() {
for (unsigned int i=0; i<gui_rpcs.size(); i++) {
GUI_RPC_CONN* gr = gui_rpcs[i];
if (gr->au_ss_state == AU_SS_GOT) {
gr->au_ss_state = AU_SS_QUIT_REQ;
}
if (gr->au_mgr_state == AU_MGR_GOT && gr->is_local) {
gr->au_mgr_state = AU_MGR_QUIT_REQ;
}
}
}

// check whether the quit messages have actually been sent
//
bool GUI_RPC_CONN_SET::quits_sent() {
for (unsigned int i=0; i<gui_rpcs.size(); i++) {
GUI_RPC_CONN* gr = gui_rpcs[i];
if (gr->au_ss_state == AU_SS_QUIT_REQ) return false;
if (gr->au_mgr_state == AU_MGR_QUIT_REQ) return false;
}
return true;
}

const char *BOINC_RCSID_88dd75dd85 = "$Id$";
21 changes: 21 additions & 0 deletions client/gui_rpc_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@

#include "network.h"

// FSM states for auto-update

#define AU_SS_INIT 0
// no get_screensaver_mode() yet
#define AU_SS_GOT 1
// got a get_screensaver_mode()
#define AU_SS_QUIT_REQ 2
// send a QUIT next time
#define AU_SS_QUIT_SENT 3
// QUIT sent

#define AU_MGR_INIT 0
#define AU_MGR_GOT 1
#define AU_MGR_QUIT_REQ 2
#define AU_MGR_QUIT_SENT 3

class GUI_RPC_CONN {
public:
int sock;
Expand All @@ -27,6 +43,9 @@ class GUI_RPC_CONN {
// if true, don't allow operations other than authentication
bool is_local;
// connection is from local host
int au_ss_state;
int au_mgr_state;

GUI_RPC_CONN(int);
~GUI_RPC_CONN();
int handle_rpc();
Expand Down Expand Up @@ -56,4 +75,6 @@ class GUI_RPC_CONN_SET {
int init();
void close();
bool recent_rpc_needs_network(double interval);
void send_quits();
bool quits_sent();
};
24 changes: 18 additions & 6 deletions client/gui_rpc_server_ops.C
Original file line number Diff line number Diff line change
Expand Up @@ -466,8 +466,12 @@ static void handle_get_host_info(char*, MIOFILE& fout) {
gstate.host_info.write(fout);
}

static void handle_get_screensaver_mode(char*, MIOFILE& fout) {
static void handle_get_screensaver_mode(GUI_RPC_CONN* gr, char*, MIOFILE& fout) {
int ss_result = gstate.ss_logic.get_ss_status();
if (gr->au_ss_state = AU_SS_QUIT_REQ) {
ss_result = SS_STATUS_QUIT;
gr->au_ss_state = AU_SS_QUIT_SENT;
}
fout.printf(
"<screensaver_mode>\n"
" <status>%d</status>\n"
Expand Down Expand Up @@ -526,7 +530,7 @@ static void handle_get_statistics(char*, MIOFILE& fout) {
fout.printf("</statistics>\n");
}

static void handle_get_cc_status(MIOFILE& fout) {
static void handle_get_cc_status(GUI_RPC_CONN* gr, MIOFILE& fout) {
fout.printf(
"<cc_status>\n"
" <network_status>%d</network_status>\n"
Expand All @@ -538,8 +542,7 @@ static void handle_get_cc_status(MIOFILE& fout) {
" <task_mode_perm>%d</task_mode_perm>\n"
" <network_mode_perm>%d</network_mode_perm>\n"
" <task_mode_delay>%f</task_mode_delay>\n"
" <network_mode_delay>%f</network_mode_delay>\n"
"</cc_status>\n",
" <network_mode_delay>%f</network_mode_delay>\n",
net_status.network_status(),
gstate.acct_mgr_info.password_error?1:0,
gstate.suspend_reason,
Expand All @@ -551,6 +554,15 @@ static void handle_get_cc_status(MIOFILE& fout) {
gstate.run_mode.delay(),
gstate.network_mode.delay()
);
if (gr->au_mgr_state == AU_MGR_QUIT_REQ) {
fout.printf(
" <manager_must_quit>1</manager_must_quit>\n"
);
gr->au_mgr_state = AU_MGR_QUIT_SENT;
}
fout.printf(
"</cc_status>\n"
);
}

static void handle_network_available(char*, MIOFILE&) {
Expand Down Expand Up @@ -859,7 +871,7 @@ int GUI_RPC_CONN::handle_rpc() {
gstate.write_tasks_gui(mf);
mf.printf("</results>\n");
} else if (match_tag(request_msg, "<get_screensaver_mode")) {
handle_get_screensaver_mode(request_msg, mf);
handle_get_screensaver_mode(this, request_msg, mf);
} else if (match_tag(request_msg, "<set_screensaver_mode")) {
handle_set_screensaver_mode(request_msg, mf);
} else if (match_tag(request_msg, "<get_file_transfers")) {
Expand All @@ -881,7 +893,7 @@ int GUI_RPC_CONN::handle_rpc() {
} else if (match_tag(request_msg, "<get_newer_version>")) {
handle_get_newer_version(mf);
} else if (match_tag(request_msg, "<get_cc_status")) {
handle_get_cc_status(mf);
handle_get_cc_status(this, mf);

// Operations that require authentication start here

Expand Down
2 changes: 1 addition & 1 deletion client/main.C
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ int initialize() {
}
#endif

retval = wait_client_mutex(10);
retval = wait_client_mutex(".", 10);
if (retval) {
fprintf(stderr,
"Another instance of BOINC is running\n"
Expand Down
2 changes: 1 addition & 1 deletion doc/project_tasks.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
list_item("db_dump",
"Write statistics data to XML files for export.
Details are <a href=db_dump.php>here</a>.
Recommended period: 7 days."
Recommended period: 1 day."
);
list_item("update_profile_pages.php",
"Generate HTML files with lists of links to user profiles,
Expand Down
31 changes: 25 additions & 6 deletions lib/filesys.C
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,17 @@ int boinc_make_dirs(const char* dirpath, const char* filepath) {
}


FILE_LOCK::FILE_LOCK() {
#ifndef _WIN32
fd = -1;
#endif
}
FILE_LOCK::~FILE_LOCK() {
#ifndef _WIN32
if (fd >= 0) close(fd);
#endif
}

int FILE_LOCK::lock(const char* filename) {
#if defined(_WIN32) && !defined(__CYGWIN32__)
handle = CreateFile(
Expand All @@ -558,9 +569,11 @@ int FILE_LOCK::lock(const char* filename) {
return 0;

#else
fd = open(
filename, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH
);
if (fd<0) {
fd = open(
filename, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH
);
}
if (fd<0) {
return -1;
}
Expand All @@ -585,12 +598,18 @@ int FILE_LOCK::unlock(const char* filename) {
perror("FILE_LOCK::unlock(): close failed.");
}
#endif
if (boinc_delete_file(filename) != 0) {
perror("FILE_LOCK::unlock: delete failed.");
}
boinc_delete_file(filename);
return 0;
}

void boinc_getcwd(char* path) {
#if defined(_WIN32) && !defined(__CYGWIN32__)
_getcwd(path, 256);
#else
getcwd(path, 256);
#endif
}

void relative_to_absolute(const char* relname, char* path) {
#if defined(_WIN32) && !defined(__CYGWIN32__)
_getcwd(path, 256);
Expand Down
3 changes: 3 additions & 0 deletions lib/filesys.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ extern "C" {
#endif
extern int boinc_rmdir(const char*);
extern int remove_project_owned_file_or_dir(const char* path);
extern void boinc_getcwd(char*);
extern void relative_to_absolute(const char* relname, char* path);
extern int boinc_make_dirs(char*, char*);
extern char boinc_failed_file[256];
Expand Down Expand Up @@ -107,6 +108,8 @@ struct FILE_LOCK {
#else
int fd;
#endif
FILE_LOCK();
~FILE_LOCK();
int lock(const char* filename);
int unlock(const char* filename);
};
Expand Down
11 changes: 7 additions & 4 deletions lib/util.C
Original file line number Diff line number Diff line change
Expand Up @@ -1281,7 +1281,7 @@ int run_program(char* dir, char* file, int argc, char** argv) {
#endif
}

static int get_client_mutex() {
static int get_client_mutex(char* dir) {
#ifdef _WIN32
char buf[MAX_PATH] = "";

Expand All @@ -1297,18 +1297,21 @@ static int get_client_mutex() {
return ERR_ALREADY_RUNNING;
}
#else
char path[1024];
static FILE_LOCK file_lock;
if (file_lock.lock(LOCK_FILE_NAME)) {

sprintf(path, "%s/%s", dir, LOCK_FILE_NAME);
if (file_lock.lock(path)) {
return ERR_ALREADY_RUNNING;
}
#endif
return 0;
}

int wait_client_mutex(double timeout) {
int wait_client_mutex(char* dir, double timeout) {
double start = dtime();
while (1) {
int retval = get_client_mutex();
int retval = get_client_mutex(dir);
if (!retval) return 0;
boinc_sleep(1);
if (dtime() - start > timeout) break;
Expand Down
2 changes: 1 addition & 1 deletion lib/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,6 @@ extern int check_security(int use_sandbox, int isManager);
#endif

extern int run_program(char* path, char* cdir, int argc, char** argv);
extern int wait_client_mutex(double timeout);
extern int wait_client_mutex(char* dir, double timeout);

#endif
Loading

0 comments on commit 46695c2

Please sign in to comment.