mirror of https://github.com/BOINC/boinc.git
parent
f08517a666
commit
7d6fce4cf4
|
@ -56,7 +56,7 @@ ARCHIVE_TARGETS = \
|
|||
mac_build/boinc.pbproj/*.pbxproj mac_build/*.lproj/*.nib/*.* \
|
||||
mac_build/*.lproj/*.strings \
|
||||
win_build/*.* win_build/*/*.dsp win_build/*/*.rct \
|
||||
INSTALL LICENSE configure \
|
||||
INSTALL LICENSE configure todo checkin_notes \
|
||||
*.in *.sub *.guess
|
||||
|
||||
tar:
|
||||
|
|
|
@ -4101,3 +4101,45 @@ Erik May 8 2003
|
|||
lib/
|
||||
Makefile.in
|
||||
app_ipc.C,h
|
||||
|
||||
Erik May 13 2003
|
||||
- Added a notion of "tentative" project.
|
||||
This means that the (URL, account ID) pair hasn't been verified,
|
||||
i.e. we haven't fetched the master page, found a scheduler,
|
||||
and done a scheduler op that verified the account ID.
|
||||
If anything fails for a tentative project, call project_add_failed().
|
||||
in the cmdline version this prints an error message,
|
||||
deletes all evidence of the project, and exits.
|
||||
TODO: implement for GUI
|
||||
- Make write_account_file() into a member function of PROJECT.
|
||||
- Got rid of CLIENT_STATE::change_project().
|
||||
The user must detach and attach.
|
||||
- CLIENT_STATE::quit_project() now takes a PROJECT*, not an int.
|
||||
Need to change the GUI code.
|
||||
- got rid of separate WIN_32 implementations of
|
||||
make_project_dir(), remove_project_dir(), make_slot_dir().
|
||||
THIS IS THE WRONG LEVEL FOR PLATFORM-DEPENDENT CODE!
|
||||
Instead, added boinc_mkdir() and boinc_rmdir()
|
||||
- added implementation docs for screensaver logic
|
||||
- test_uc.php: wait for a second before running client.
|
||||
On fast computers the client runs before feeder has seeded shmem.
|
||||
|
||||
client/
|
||||
account.C,h
|
||||
client_state.C,h
|
||||
client_types.C,h
|
||||
cs_scheduler.C
|
||||
file_names.C
|
||||
main.C
|
||||
scheduler_op.C,h
|
||||
ss_logic.C
|
||||
win/
|
||||
wingui.cpp
|
||||
wingui_mainwindow.cpp
|
||||
doc/
|
||||
client_app.html
|
||||
client_app_graphic.html
|
||||
lib/
|
||||
filesys.C,y
|
||||
test/
|
||||
test_uc.php
|
||||
|
|
|
@ -26,34 +26,6 @@
|
|||
|
||||
#include "account.h"
|
||||
|
||||
int write_account_file(
|
||||
char* master_url, char* authenticator, char* project_prefs
|
||||
) {
|
||||
char path[256];
|
||||
FILE* f;
|
||||
int retval;
|
||||
|
||||
get_account_filename(master_url, path);
|
||||
f = fopen(TEMP_FILE_NAME, "w");
|
||||
if (!f) return ERR_FOPEN;
|
||||
|
||||
fprintf(f,
|
||||
"<account>\n"
|
||||
" <master_url>%s</master_url>\n"
|
||||
" <authenticator>%s</authenticator>\n",
|
||||
master_url,
|
||||
authenticator
|
||||
);
|
||||
if (project_prefs) {
|
||||
fprintf(f, "%s", project_prefs);
|
||||
}
|
||||
fprintf(f, "</account>\n");
|
||||
fclose(f);
|
||||
retval = boinc_rename(TEMP_FILE_NAME, path);
|
||||
if (retval) return ERR_RENAME;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CLIENT_STATE::parse_account_files() {
|
||||
DIRREF dir;
|
||||
char name[256];
|
||||
|
@ -87,17 +59,19 @@ int CLIENT_STATE::add_project(char* master_url, char* authenticator) {
|
|||
|
||||
// create project state
|
||||
//
|
||||
retval = write_account_file(master_url, authenticator);
|
||||
project = new PROJECT;
|
||||
strcpy(project->master_url, master_url);
|
||||
strcpy(project->authenticator, authenticator);
|
||||
project->tentative = true;
|
||||
retval = project->write_account_file();
|
||||
if (retval) return retval;
|
||||
|
||||
get_account_filename(master_url, path);
|
||||
f = fopen(path, "r");
|
||||
if (!f) return ERR_FOPEN;
|
||||
project = new PROJECT;
|
||||
retval = project->parse_account(f);
|
||||
fclose(f);
|
||||
if(retval) {
|
||||
return retval;
|
||||
}
|
||||
if (retval) return retval;
|
||||
|
||||
// remove any old files
|
||||
//
|
||||
|
@ -109,6 +83,13 @@ int CLIENT_STATE::add_project(char* master_url, char* authenticator) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Wrong approach.
|
||||
// The user must detach and reattach.
|
||||
// In any case the following has a major bug:
|
||||
// the call to remove_project_dir() won't work because
|
||||
// it gets the new, not the old, project URL
|
||||
//
|
||||
int CLIENT_STATE::change_project(
|
||||
int index, char* master_url, char* authenticator
|
||||
) {
|
||||
|
@ -121,7 +102,7 @@ int CLIENT_STATE::change_project(
|
|||
//
|
||||
if (lookup_project(master_url)) return -1;
|
||||
|
||||
// delete old file
|
||||
// delete old account file
|
||||
//
|
||||
project = projects[index];
|
||||
get_account_filename(project->master_url, path);
|
||||
|
@ -147,33 +128,42 @@ int CLIENT_STATE::change_project(
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int CLIENT_STATE::quit_project(int index) {
|
||||
PROJECT* project = NULL;
|
||||
// TODO: see if any activities are in progress for this project, and stop them
|
||||
//
|
||||
int CLIENT_STATE::quit_project(PROJECT* project) {
|
||||
PROJECT* p;
|
||||
vector <PROJECT*>::iterator iter;
|
||||
int curindex = 0;
|
||||
char path[256];
|
||||
int retval;
|
||||
|
||||
// find project and remove it from the vector
|
||||
//
|
||||
for (iter = projects.begin(); iter != projects.end(); iter++) {
|
||||
if (curindex == index) {
|
||||
project = *iter;
|
||||
p = *iter;
|
||||
if (p == project) {
|
||||
projects.erase(iter);
|
||||
break;
|
||||
}
|
||||
curindex++;
|
||||
}
|
||||
if (project == NULL) return -1;
|
||||
|
||||
// delete file
|
||||
char path[256];
|
||||
int retval;
|
||||
// delete account file
|
||||
//
|
||||
get_account_filename(project->master_url, path);
|
||||
retval = file_delete(path);
|
||||
|
||||
// delete project; //also somewhere else?
|
||||
|
||||
// if tentative, there are no activities so we can safely delete everything
|
||||
//
|
||||
if (project->tentative) {
|
||||
// remove project directory and its contents
|
||||
//
|
||||
remove_project_dir(*project);
|
||||
delete project;
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
AfxMessageBox("Please restart the client to complete the quit.", MB_OK, 0);
|
||||
AfxMessageBox("Please restart the client to complete the quit.", MB_OK, 0);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
#ifndef _ACCOUNT_
|
||||
#define _ACCOUNT_
|
||||
|
||||
extern int write_account_file(
|
||||
char* master_url, char* authenticator, char* project_prefs=0
|
||||
);
|
||||
extern int add_new_project();
|
||||
extern int parse_account_files();
|
||||
|
||||
|
|
|
@ -488,13 +488,11 @@ int CLIENT_STATE::check_suspend_activities() {
|
|||
|
||||
if (should_suspend) {
|
||||
if (!activities_suspended) {
|
||||
if (log_flags.task_debug) printf("SUSPENDING ACTIVITIES\n");
|
||||
active_tasks.suspend_all();
|
||||
show_message(NULL, susp_msg, MSG_INFO);
|
||||
}
|
||||
} else {
|
||||
if (activities_suspended) {
|
||||
if (log_flags.task_debug) printf("UNSUSPENDING ACTIVITIES\n");
|
||||
active_tasks.unsuspend_all();
|
||||
show_message(NULL, "Resuming activity", MSG_INFO);
|
||||
}
|
||||
|
|
|
@ -168,8 +168,8 @@ public:
|
|||
int report_result_error(RESULT &res, int err_num, char *err_msg);
|
||||
// flag a result as having an error
|
||||
int add_project(char* master_url, char* authenticator);
|
||||
int change_project(int index, char* master_url, char* authenticator);
|
||||
int quit_project(int index);
|
||||
//int change_project(int index, char* master_url, char* authenticator);
|
||||
int quit_project(PROJECT*);
|
||||
private:
|
||||
PROJECT* find_project_with_overdue_results();
|
||||
bool some_project_rpc_ok();
|
||||
|
|
|
@ -57,11 +57,43 @@ PROJECT::PROJECT() {
|
|||
debt_order = 0;
|
||||
master_url_fetch_pending = false;
|
||||
sched_rpc_pending = false;
|
||||
tentative = false;
|
||||
}
|
||||
|
||||
PROJECT::~PROJECT() {
|
||||
}
|
||||
|
||||
// write account_*.xml file
|
||||
//
|
||||
int PROJECT::write_account_file() {
|
||||
char path[256];
|
||||
FILE* f;
|
||||
int retval;
|
||||
|
||||
get_account_filename(master_url, path);
|
||||
f = fopen(TEMP_FILE_NAME, "w");
|
||||
if (!f) return ERR_FOPEN;
|
||||
|
||||
fprintf(f,
|
||||
"<account>\n"
|
||||
" <master_url>%s</master_url>\n"
|
||||
" <authenticator>%s</authenticator>\n",
|
||||
master_url,
|
||||
authenticator
|
||||
);
|
||||
if (strlen(project_specific_prefs)) {
|
||||
fprintf(f, "%s", project_specific_prefs);
|
||||
}
|
||||
if (tentative) {
|
||||
fprintf(f, " <tentative/>\n");
|
||||
}
|
||||
fprintf(f, "</account>\n");
|
||||
fclose(f);
|
||||
retval = boinc_rename(TEMP_FILE_NAME, path);
|
||||
if (retval) return ERR_RENAME;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// parse project fields from account_*.xml
|
||||
//
|
||||
int PROJECT::parse_account(FILE* in) {
|
||||
|
@ -83,6 +115,10 @@ int PROJECT::parse_account(FILE* in) {
|
|||
else if (parse_double(buf, "<resource_share>", resource_share)) continue;
|
||||
else if (match_tag(buf, "<send_email/>")) continue;
|
||||
else if (match_tag(buf, "<show_email/>")) continue;
|
||||
else if (match_tag(buf, "<tentative/>")) {
|
||||
tentative = true;
|
||||
continue;
|
||||
}
|
||||
else if (match_tag(buf, "<project_specific>")) {
|
||||
retval = copy_element_contents(
|
||||
in,
|
||||
|
@ -243,11 +279,12 @@ void PROJECT::copy_state_fields(PROJECT& p) {
|
|||
safe_strcpy(code_sign_key, p.code_sign_key);
|
||||
}
|
||||
|
||||
char *PROJECT::get_project_name() {
|
||||
if(!strcmp(project_name, ""))
|
||||
return master_url;
|
||||
else
|
||||
char* PROJECT::get_project_name() {
|
||||
if (strlen(project_name)) {
|
||||
return project_name;
|
||||
} else {
|
||||
return master_url;
|
||||
}
|
||||
}
|
||||
|
||||
int APP::parse(FILE* in) {
|
||||
|
|
|
@ -59,7 +59,7 @@ public:
|
|||
|
||||
// the following items come from client_state.xml
|
||||
// They may depend on the host as well as user and project
|
||||
// NOTE: if you add anything, add it copy_state_fields() as well!!!
|
||||
// NOTE: if you add anything, add it to copy_state_fields() also!!!
|
||||
//
|
||||
vector<STRING256> scheduler_urls; // where to find scheduling servers
|
||||
char project_name[256]; // descriptive. not unique
|
||||
|
@ -82,8 +82,8 @@ public:
|
|||
// of this project (or zero)
|
||||
bool master_url_fetch_pending;
|
||||
// need to fetch and parse the master URL
|
||||
bool sched_rpc_pending;
|
||||
// need to contact the scheduling server for user/project info
|
||||
bool sched_rpc_pending; // contact scheduling server for preferences
|
||||
bool tentative; // master URL and account ID not confirmed
|
||||
char code_sign_key[MAX_BLOB_LEN];
|
||||
|
||||
// the following items are transient; not saved in state file
|
||||
|
@ -95,6 +95,7 @@ public:
|
|||
~PROJECT();
|
||||
void copy_state_fields(PROJECT&);
|
||||
char *get_project_name();
|
||||
int write_account_file();
|
||||
int parse_account(FILE*);
|
||||
int parse_state(FILE*);
|
||||
int write_state(FILE*);
|
||||
|
|
|
@ -396,17 +396,18 @@ int CLIENT_STATE::handle_scheduler_reply(
|
|||
// deal with project preferences (should always be there)
|
||||
//
|
||||
if (sr.project_prefs_xml) {
|
||||
char path[256];
|
||||
|
||||
retval = write_account_file(
|
||||
project->master_url, project->authenticator, sr.project_prefs_xml
|
||||
);
|
||||
strcpy(project->project_specific_prefs, sr.project_prefs_xml);
|
||||
retval = project->write_account_file();
|
||||
if (retval) return retval;
|
||||
|
||||
#if 0
|
||||
char path[256];
|
||||
get_account_filename(project->master_url, path);
|
||||
f = fopen(path, "r");
|
||||
if (!f) return ERR_FOPEN;
|
||||
project->parse_account(f);
|
||||
fclose(f);
|
||||
#endif
|
||||
}
|
||||
|
||||
// if the scheduler reply includes a code-signing key,
|
||||
|
|
|
@ -89,55 +89,15 @@ void get_slot_dir(int slot, char* path) {
|
|||
sprintf(path, "%s%s%d", SLOTS_DIR, PATH_SEPARATOR, slot);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
// Double check permissions for CreateDirectory
|
||||
|
||||
int make_project_dir(PROJECT& p) {
|
||||
char buf[256],buf2[256];
|
||||
|
||||
CreateDirectory(PROJECTS_DIR, NULL);
|
||||
escape_project_url(p.master_url, buf);
|
||||
sprintf(buf2, "%s%s%s", PROJECTS_DIR, PATH_SEPARATOR, buf);
|
||||
CreateDirectory(buf2, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int remove_project_dir(PROJECT& p) {
|
||||
char buf[256],buf2[256];
|
||||
|
||||
escape_project_url(p.master_url, buf);
|
||||
sprintf(buf2, "%s%s%s", PROJECTS_DIR, PATH_SEPARATOR, buf);
|
||||
clean_out_dir(buf2);
|
||||
RemoveDirectory(buf2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns the location of a numbered slot directory
|
||||
//
|
||||
int make_slot_dir(int slot) {
|
||||
if(slot<0) {
|
||||
fprintf(stderr, "error: make_slot_dir: negative slot\n");
|
||||
return ERR_NEG;
|
||||
}
|
||||
char buf[256];
|
||||
CreateDirectory(SLOTS_DIR, NULL);
|
||||
get_slot_dir(slot, buf);
|
||||
CreateDirectory(buf, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// Create the directory for the project p
|
||||
//
|
||||
int make_project_dir(PROJECT& p) {
|
||||
char buf[256],buf2[256];
|
||||
|
||||
mkdir(PROJECTS_DIR, 0777);
|
||||
boinc_mkdir(PROJECTS_DIR);
|
||||
escape_project_url(p.master_url, buf);
|
||||
sprintf(buf2, "%s%s%s", PROJECTS_DIR, PATH_SEPARATOR, buf);
|
||||
mkdir(buf2, 0777);
|
||||
boinc_mkdir(buf2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -147,7 +107,7 @@ int remove_project_dir(PROJECT& p) {
|
|||
escape_project_url(p.master_url, buf);
|
||||
sprintf(buf2, "%s%s%s", PROJECTS_DIR, PATH_SEPARATOR, buf);
|
||||
clean_out_dir(buf2);
|
||||
// rmdir(buf2);
|
||||
boinc_rmdir(buf2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -159,14 +119,12 @@ int make_slot_dir(int slot) {
|
|||
fprintf(stderr, "error: make_slot_dir: negative slot\n");
|
||||
return ERR_NEG;
|
||||
}
|
||||
mkdir(SLOTS_DIR, 0777);
|
||||
boinc_mkdir(SLOTS_DIR);
|
||||
get_slot_dir(slot, buf);
|
||||
mkdir(buf, 0777);
|
||||
boinc_mkdir(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void get_account_filename(char* master_url, char* path) {
|
||||
char buf[256];
|
||||
escape_project_url(master_url, buf);
|
||||
|
|
|
@ -42,16 +42,42 @@
|
|||
void create_curtain(){}
|
||||
void delete_curtain(){}
|
||||
|
||||
// This gets called when the client fails to add a project
|
||||
//
|
||||
void project_add_failed(PROJECT* project) {
|
||||
if (project->scheduler_urls.size()) {
|
||||
printf(
|
||||
"BOINC failed to log in to %s.\n "
|
||||
"Please check your account ID and try again.\n",
|
||||
project->master_url
|
||||
);
|
||||
} else {
|
||||
printf(
|
||||
"BOINC couldn't get main page for %s.\n"
|
||||
"Please check the URL and try again.\n",
|
||||
project->master_url
|
||||
);
|
||||
}
|
||||
gstate.quit_project(project);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Display a message to the user.
|
||||
// Depending on the priority, the message may be more or less obtrusive
|
||||
//
|
||||
void show_message(PROJECT *p, char* message, int priority) {
|
||||
const char* proj = p?p->project_name:"BOINC";
|
||||
char* x;
|
||||
|
||||
if (p) {
|
||||
x = p->get_project_name();
|
||||
} else {
|
||||
x = "BOINC";
|
||||
}
|
||||
switch (priority) {
|
||||
case MSG_ERROR:
|
||||
fprintf(stderr, "%s [%s] %s\n", timestamp(), proj, message);
|
||||
fprintf(stderr, "%s [%s] %s\n", timestamp(), x, message);
|
||||
default:
|
||||
printf("%s [%s] %s\n", timestamp(), proj, message);
|
||||
printf("%s [%s] %s\n", timestamp(), x, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,19 +85,19 @@ void show_message(PROJECT *p, char* message, int priority) {
|
|||
// and create an account file
|
||||
//
|
||||
int add_new_project() {
|
||||
char master_url[256];
|
||||
char authenticator[256];
|
||||
PROJECT project;
|
||||
|
||||
printf("Enter the URL of the project: ");
|
||||
scanf("%s", master_url);
|
||||
scanf("%s", project.master_url);
|
||||
printf(
|
||||
"You should have already registered with the project\n"
|
||||
"and received an account key by email.\n"
|
||||
"Paste the account key here: "
|
||||
);
|
||||
scanf("%s", authenticator);
|
||||
scanf("%s", project.authenticator);
|
||||
|
||||
write_account_file(master_url, authenticator);
|
||||
project.tentative = true;
|
||||
project.write_account_file();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,12 +32,35 @@
|
|||
#include "log_flags.h"
|
||||
#include "scheduler_op.h"
|
||||
|
||||
extern void project_add_failed(PROJECT*);
|
||||
|
||||
SCHEDULER_OP::SCHEDULER_OP(HTTP_OP_SET* h) {
|
||||
state = SCHEDULER_OP_STATE_IDLE;
|
||||
http_op.http_op_state = HTTP_STATE_IDLE;
|
||||
http_ops = h;
|
||||
}
|
||||
|
||||
// see if there's a pending master file fetch. start it if so.
|
||||
//
|
||||
bool SCHEDULER_OP::check_master_fetch_start() {
|
||||
int retval;
|
||||
|
||||
project = gstate.next_project_master_pending();
|
||||
if (project) {
|
||||
retval = init_master_fetch(project);
|
||||
if (retval) {
|
||||
if (project->tentative) {
|
||||
project_add_failed(project);
|
||||
} else {
|
||||
project->master_fetch_failures++;
|
||||
backoff(project, "Master file fetch failed\n");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// try to get enough work to bring us up to max buffer level
|
||||
//
|
||||
int SCHEDULER_OP::init_get_work() {
|
||||
|
@ -55,14 +78,7 @@ int SCHEDULER_OP::init_get_work() {
|
|||
return retval;
|
||||
}
|
||||
} else {
|
||||
project = gstate.next_project_master_pending();
|
||||
if (project) {
|
||||
retval = init_master_fetch(project);
|
||||
if (retval) {
|
||||
sprintf(err_msg, "init_master_fetch failed, error %d\n", retval);
|
||||
backoff(project, err_msg);
|
||||
}
|
||||
}
|
||||
check_master_fetch_start();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -344,26 +360,23 @@ bool SCHEDULER_OP::poll() {
|
|||
// it may be the wrong URL. notify the user
|
||||
//
|
||||
if (project->scheduler_urls.size() == 0) {
|
||||
sprintf(err_msg,
|
||||
"Could not contact %s. Make sure this is the correct project URL.",
|
||||
err_url
|
||||
);
|
||||
show_message(project, err_msg, MSG_ERROR);
|
||||
project->master_fetch_failures++;
|
||||
backoff(project, err_msg);
|
||||
if (project->tentative) {
|
||||
project_add_failed(project);
|
||||
} else {
|
||||
sprintf(err_msg,
|
||||
"Could not contact any schedulers for %s.",
|
||||
err_url
|
||||
);
|
||||
show_message(project, err_msg, MSG_ERROR);
|
||||
project->master_fetch_failures++;
|
||||
backoff(project, err_msg);
|
||||
}
|
||||
}
|
||||
|
||||
// See if need to read master file for another project
|
||||
// See if need to read master file for another project;
|
||||
// if not, we're done for now
|
||||
//
|
||||
project = gstate.next_project_master_pending();
|
||||
if (project) {
|
||||
retval = init_master_fetch(project);
|
||||
if (retval) {
|
||||
project->master_fetch_failures++;
|
||||
backoff(project, "Master file fetch failed\n");
|
||||
err_url = project->master_url;
|
||||
}
|
||||
} else {
|
||||
if (!check_master_fetch_start()) {
|
||||
state = SCHEDULER_OP_STATE_IDLE;
|
||||
if (log_flags.sched_op_debug) {
|
||||
printf("Scheduler_op: return to idle state\n");
|
||||
|
@ -402,8 +415,7 @@ bool SCHEDULER_OP::poll() {
|
|||
} else {
|
||||
scheduler_op_done = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
scheduler_op_done = true;
|
||||
}
|
||||
}
|
||||
|
@ -416,14 +428,27 @@ bool SCHEDULER_OP::poll() {
|
|||
}
|
||||
gstate.handle_scheduler_reply(project, scheduler_url, nresults);
|
||||
|
||||
// if we asked for work and didn't get any,
|
||||
// back off this project
|
||||
// if this was a tentative project and we didn't get user name,
|
||||
// the account ID must be bad. Tell the user.
|
||||
//
|
||||
if (must_get_work && nresults==0) {
|
||||
backoff(project, "No work from project\n");
|
||||
if (project->tentative) {
|
||||
if (strlen(project->user_name)) {
|
||||
project->tentative = false;
|
||||
project->write_account_file();
|
||||
} else {
|
||||
project_add_failed(project);
|
||||
}
|
||||
} else {
|
||||
project->nrpc_failures = 0;
|
||||
project->min_rpc_time = 0;
|
||||
|
||||
// if we asked for work and didn't get any,
|
||||
// back off this project
|
||||
//
|
||||
if (must_get_work && nresults==0) {
|
||||
backoff(project, "No work from project\n");
|
||||
} else {
|
||||
project->nrpc_failures = 0;
|
||||
project->min_rpc_time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// if we didn't get all the work we needed,
|
||||
|
|
|
@ -87,6 +87,7 @@ struct SCHEDULER_OP {
|
|||
int set_min_rpc_time(PROJECT*);
|
||||
bool update_urls(PROJECT& project, vector<STRING256> &urls);
|
||||
int start_op(PROJECT*);
|
||||
bool check_master_fetch_start();
|
||||
void backoff(PROJECT* p, char *error_msg);
|
||||
int start_rpc();
|
||||
int parse_master_file(vector<STRING256>&);
|
||||
|
|
|
@ -71,7 +71,7 @@ void SS_LOGIC::poll() {
|
|||
} else {
|
||||
if (time(0)>ack_deadline) {
|
||||
do_boinc_logo_ss = true;
|
||||
sprintf(ss_msg, "App can't display graphics");
|
||||
strcpy(ss_msg, "App can't display graphics");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -81,7 +81,7 @@ void SS_LOGIC::poll() {
|
|||
ack_deadline = time(0) + 5;
|
||||
} else {
|
||||
do_boinc_logo_ss = true;
|
||||
sprintf(ss_msg, "No work available");
|
||||
strcpy(ss_msg, "No work available");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,18 +23,18 @@
|
|||
#include "wingui_mainwindow.h"
|
||||
|
||||
void show_message(PROJECT* p, char* message, int priority) {
|
||||
char proj_name[256];
|
||||
char* x;
|
||||
|
||||
if (p) {
|
||||
safe_strncpy( proj_name, p->get_project_name(), sizeof(proj_name) );
|
||||
x = p->get_project_name();
|
||||
} else {
|
||||
safe_strncpy( proj_name, "BOINC", sizeof(proj_name) );
|
||||
x = "BOINC";
|
||||
}
|
||||
|
||||
if(g_myWnd) {
|
||||
g_myWnd->MessageUser(proj_name, message, priority);
|
||||
g_myWnd->MessageUser(x, message, priority);
|
||||
} else {
|
||||
fprintf(stderr, "%s: %s (priority: %s)\n", proj_name, message, priority);
|
||||
fprintf(stderr, "%s: %s (priority: %s)\n", x, message, priority);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1057,6 +1057,7 @@ void CMainWindow::OnCommandConnectionConnectNow()
|
|||
NetClose();
|
||||
}
|
||||
|
||||
#if 0
|
||||
//////////
|
||||
// CMainWindow::OnCommandProjectRelogin
|
||||
// arguments: void
|
||||
|
@ -1083,6 +1084,7 @@ void CMainWindow::OnCommandProjectRelogin()
|
|||
gstate.change_project(i, dlg.m_strUrl.GetBuffer(0), dlg.m_strAuth.GetBuffer(0));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////
|
||||
// CMainWindow::OnCommandProjectQuit
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<h2>Core/app interaction (basic)</h2>
|
||||
|
||||
TO BE WRITTEN.
|
||||
<p>
|
||||
Explain startup files
|
||||
<p>
|
||||
Explain shared memory mechanism in general
|
||||
<p>
|
||||
Explain work-related use of shmem
|
|
@ -0,0 +1,14 @@
|
|||
<h2>Screensaver/core/app interaction (graphics)</h2>
|
||||
|
||||
TO BE WRITTEN
|
||||
|
||||
<p>
|
||||
Explain graphics startup files
|
||||
<p>
|
||||
Explain graphics modes of apps
|
||||
<p>
|
||||
Explain graphics use of shmem
|
||||
<p>
|
||||
Explain screensaver module
|
||||
<p>
|
||||
Explain screensaver logic in core
|
|
@ -263,6 +263,22 @@ int boinc_rename(char* old, char* newf) {
|
|||
return rename(old, newf);
|
||||
}
|
||||
|
||||
int boinc_mkdir(char* name) {
|
||||
#ifdef _WIN32
|
||||
return CreateDirectory(name, NULL);
|
||||
#else
|
||||
return mkdir(name, 0777);
|
||||
#endif
|
||||
}
|
||||
|
||||
int boinc_rmdir(char* name) {
|
||||
#ifdef _WIN32
|
||||
return RemoveDirectory(name, NULL);
|
||||
#else
|
||||
return rmdir(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void full_path(char* relname, char* path) {
|
||||
_getcwd(path, 256);
|
||||
|
|
|
@ -42,6 +42,8 @@ extern int boinc_link(char *existing, char *new_link);
|
|||
extern int clean_out_dir(char*);
|
||||
extern int dir_size(char* dirpath, double&);
|
||||
extern int boinc_rename(char* old, char* newf);
|
||||
extern int boinc_mkdir(char*);
|
||||
extern int boinc_rmdir(char*);
|
||||
#ifdef _WIN32
|
||||
extern void full_path(char* relname, char* path);
|
||||
#endif
|
||||
|
|
69
todo
69
todo
|
@ -1,11 +1,13 @@
|
|||
-----------------------
|
||||
BUGS (arranged from high to low priority)
|
||||
-----------------------
|
||||
- CPU benchmarks take way too long (linux)
|
||||
- Client treats URL "maggie/ap/" different than URL "maggie/ap",
|
||||
though this isn't really a bug it might be good to fix anyway
|
||||
- global battery/user active prefs are always true in the client
|
||||
- Client should display "Upload failed" and "Download failed" when failure occurs
|
||||
- Result status should say "downloading files", "uploading files", etc.
|
||||
- GUI client should display "Upload failed" and "Download failed"
|
||||
in transfers tab when failure occurs
|
||||
- GUI: Result status should say "downloading files", "uploading files", etc.
|
||||
- message window should reposition to bottom when new message
|
||||
- show_message should expect \n, discard it if GUI
|
||||
- Win GUI: line between menus and tabs
|
||||
|
@ -19,29 +21,68 @@ BUGS (arranged from high to low priority)
|
|||
run_on_startup
|
||||
hangup_if_dialed
|
||||
- trim leading/trailing spaces from account ID (Win GUI)
|
||||
- I entered in a wrong URL - there was no obvious feedback that it wasn't correct.
|
||||
Messages showed up in the messages tab, but I was looking at the progress tab.
|
||||
Shouldn't the client expect something from the server? If it doesn't get it,
|
||||
especially on logging in for the first time, you should get an obvious warning.
|
||||
- when i quit a project, I have to exit and restart the client, which is ugly.
|
||||
- after quitting a project, the project name still showed up in gray in the projects
|
||||
list - I could right click on it to "relogin" (which did nothing) or "quit project"
|
||||
- after quitting a project, the project name still showed up in gray
|
||||
in the projects list - I could right click on it to "relogin"
|
||||
(which did nothing) or "quit project"
|
||||
which I thought I already did.
|
||||
- consider warning message during windows (and perhaps other platforms)
|
||||
install that checks to see if the BOINC directory already exists,
|
||||
and if so, should the user overwrite it? or upgrade it?
|
||||
- After running all night (on Win98) I shook the mouse to wake up the blank screen, and
|
||||
all I saw was the top half of the screen was solid gray, and the bottom half the
|
||||
bottom half of the astropulse graphics. They weren't moving. The computer was frozen.
|
||||
- After running all night (on Win98) I shook the mouse to wake up
|
||||
the blank screen, and all I saw was the top half of the screen
|
||||
was solid gray, and the bottom half the
|
||||
bottom half of the astropulse graphics.
|
||||
They weren't moving. The computer was frozen.
|
||||
I had to ctrl-alt-del to restart.
|
||||
|
||||
-----------------------
|
||||
HIGH-PRIORITY (should do for beta test)
|
||||
-----------------------
|
||||
|
||||
On "add project" the core client should immediately attempt to
|
||||
get project master page and verify user account.
|
||||
If failure, let user retype URL/ID
|
||||
"Add project" behavior:
|
||||
Goal: give user timely feedback if bad project URL or account ID;
|
||||
don't leave bad project files sitting around
|
||||
|
||||
A project addition is "successful" when
|
||||
1) the client fetches the master page,
|
||||
2) the master page has at least one scheduler URL
|
||||
3) the client contacts a scheduler and gets a user name back.
|
||||
|
||||
The cmdline and GUI clients need to inform the user if a project
|
||||
add is not successful, since it probably means the master URL
|
||||
or account ID were typed in wrong.
|
||||
|
||||
A project is "tentative" if the above hasn't happened yet.
|
||||
This is flagged in the project file (<tentative/>) and in memory
|
||||
|
||||
A "failure event" is
|
||||
- master fetch fails
|
||||
- master page has no scheduler URLs
|
||||
- scheduler RPC fails
|
||||
- scheduler RPC returns no user name
|
||||
A "success event" is
|
||||
- scheduler RPC returns user name
|
||||
|
||||
cmdline client
|
||||
first time (no projects initially) or -add_new_project flag:
|
||||
new project is tentative (write flag to project file)
|
||||
if failure event occurs for tentative project:
|
||||
project_add_fail(PROJECT&)
|
||||
print "check URL and account ID" message
|
||||
delete project file
|
||||
exit
|
||||
If success event occurs for tentative project
|
||||
project_add_succeed(PROJECT&)
|
||||
clear tentative flag, rewrite account file
|
||||
|
||||
GUI client:
|
||||
first-time dialog or "attach to project" command:
|
||||
show a modal dialog
|
||||
("verifying account" w/ "cancel" button)
|
||||
project_add_fail(PROJECT&)
|
||||
replace w/ modal error dialog w/ retry, cancel
|
||||
project_add_succeed(PROJECT&)
|
||||
|
||||
Delete files if needed to honor disk usage constraint
|
||||
should include per-result constraints (e.g. giant stderr files)
|
||||
|
|
Loading…
Reference in New Issue