*** empty log message ***

svn path=/trunk/boinc/; revision=2506
This commit is contained in:
David Anderson 2003-10-19 02:54:35 +00:00
parent 976b549a24
commit 0790b9b2aa
8 changed files with 92 additions and 43 deletions

View File

@ -6901,3 +6901,21 @@ David 18 Oct 2003
cs_statefile.C (new)
main.C
maybe_gui.h (removed)
David 18 Oct 2003
- When reset (or detach from) a process, wait for running applications to exit
before doing other things (e.g., deleting files,
which will fail is processes have them open)
Implementation: exit_tasks() etc. now take a PROJECT* arg
- When a master file fetch fails on a tentative project (e.g. bad URL)
avoid a situation where we remove the HTTP_OP,
then detach_project() tries to remove it a second time
- print messages when reset/detach
client/
app.C,h
client_state.C,h
prefs.C
scheduler_op.C
win/
wingui.h

View File

@ -759,8 +759,10 @@ bool ACTIVE_TASK_SET::check_rsc_limits_exceeded() {
return false;
}
// The application has done something wrong.
// May as well send it a kill signal.
// If process is running, send it a kill signal
// This is done when
// 1) project is reset or detached
// 2) app has exceeded CPU, disk, or mem limits
//
int ACTIVE_TASK::abort() {
if (state == PROCESS_RUNNING) {
@ -811,37 +813,42 @@ void ACTIVE_TASK::check_graphics_mode_ack() {
}
}
// send quit signal to all tasks.
// If they don't exit in one second, send them a kill signal
// send quit signal to all tasks in the project
// (or all tasks, if zero).
// If they don't exit in 5, send them a kill signal
// and wait up to 5 more seconds to exit.
// TODO: unsuspend active tasks so they have a chance to checkpoint
//
int ACTIVE_TASK_SET::exit_tasks() {
request_tasks_exit();
int ACTIVE_TASK_SET::exit_tasks(PROJECT* proj) {
request_tasks_exit(proj);
// Wait 5 seconds for them to exit normally; if they don't then kill them
//
if (wait_for_exit(5)) {
kill_tasks();
if (wait_for_exit(5, proj)) {
kill_tasks(proj);
}
wait_for_exit(5, proj);
get_cpu_times();
return 0;
}
// Wait up to wait_time seconds for all processes to exit
// Wait up to wait_time seconds for processes to exit
// If proj is zero, wait for all processes, else that project's
// NOTE: it's bad form to sleep, but it would be complex to avoid it here
//
int ACTIVE_TASK_SET::wait_for_exit(double wait_time) {
int ACTIVE_TASK_SET::wait_for_exit(double wait_time, PROJECT* proj) {
bool all_exited;
unsigned int i,n;
ACTIVE_TASK *atp;
for (i=0; i<10; i++) {
boinc_sleep(wait_time/10.0);
all_exited = true;
for (n=0; n<active_tasks.size(); n++) {
atp = active_tasks[n];
if (proj && atp->wup->project != proj) continue;
if (!atp->task_exited()) {
all_exited = false;
break;
@ -849,11 +856,29 @@ int ACTIVE_TASK_SET::wait_for_exit(double wait_time) {
}
if (all_exited) return 0;
boinc_sleep(wait_time/10.0);
}
return -1;
}
int ACTIVE_TASK_SET::abort_project(PROJECT* project) {
vector<ACTIVE_TASK*>::iterator task_iter;
ACTIVE_TASK* atp;
exit_tasks(project);
task_iter = active_tasks.begin();
while (task_iter != active_tasks.end()) {
atp = *task_iter;
if (atp->result->project == project) {
task_iter = active_tasks.erase(task_iter);
} else {
task_iter++;
}
}
return 0;
}
// Find the ACTIVE_TASK in the current set with the matching PID
//
ACTIVE_TASK* ACTIVE_TASK_SET::lookup_pid(int pid) {
@ -917,11 +942,12 @@ void ACTIVE_TASK_SET::unsuspend_all() {
// Send quit signal to all currently running tasks
//
void ACTIVE_TASK_SET::request_tasks_exit() {
void ACTIVE_TASK_SET::request_tasks_exit(PROJECT* proj) {
unsigned int i;
ACTIVE_TASK *atp;
for (i=0; i<active_tasks.size(); i++) {
atp = active_tasks[i];
if (proj && atp->wup->project != proj) continue;
atp->request_exit();
}
}
@ -929,11 +955,12 @@ void ACTIVE_TASK_SET::request_tasks_exit() {
// Send kill signal to all currently running tasks
// Don't wait for them to exit
//
void ACTIVE_TASK_SET::kill_tasks() {
void ACTIVE_TASK_SET::kill_tasks(PROJECT* proj) {
unsigned int i;
ACTIVE_TASK *atp;
for (i=0; i<active_tasks.size(); i++) {
atp = active_tasks[i];
if (proj && atp->wup->project != proj) continue;
atp->kill_task();
}
}

View File

@ -132,16 +132,17 @@ public:
active_tasks_v active_tasks;
int insert(ACTIVE_TASK*);
int remove(ACTIVE_TASK*);
int wait_for_exit(double);
ACTIVE_TASK* lookup_pid(int);
ACTIVE_TASK* lookup_result(RESULT*);
bool poll();
void suspend_all();
void unsuspend_all();
int restart_tasks();
void request_tasks_exit();
int exit_tasks();
void kill_tasks();
void request_tasks_exit(PROJECT* p=0);
int wait_for_exit(double, PROJECT* p=0);
int exit_tasks(PROJECT* p=0);
void kill_tasks(PROJECT* p=0);
int abort_project(PROJECT*);
void get_cpu_times();
bool check_app_exited();
bool check_rsc_limits_exceeded();

View File

@ -175,9 +175,11 @@ int CLIENT_STATE::init() {
// printing the platform name here helps bug reports because users often
// give us this line but don't say what platform they have
msg_printf(NULL, MSG_INFO, "Starting BOINC client version %d.%02d (%s)",
core_client_major_version, core_client_minor_version, platform_name
);
//
msg_printf(
NULL, MSG_INFO, "Starting BOINC client version %d.%02d (%s)",
core_client_major_version, core_client_minor_version, platform_name
);
// parse account files.
// If there are none, prompt user for project URL and create file
@ -931,20 +933,13 @@ int CLIENT_STATE::reset_project(PROJECT* project) {
unsigned int i;
APP_VERSION* avp;
APP* app;
ACTIVE_TASK* atp;
vector<APP*>::iterator app_iter;
vector<APP_VERSION*>::iterator avp_iter;
RESULT* rp;
PERS_FILE_XFER* pxp;
for (i=0; i<active_tasks.active_tasks.size(); i++) {
atp = active_tasks.active_tasks[i];
if (atp->result->project == project) {
atp->abort();
active_tasks.remove(atp);
i--;
}
}
msg_printf(project, MSG_INFO, "Resetting project");
active_tasks.abort_project(project);
for (i=0; i<pers_file_xfers->pers_file_xfers.size(); i++) {
pxp = pers_file_xfers->pers_file_xfers[i];
@ -957,6 +952,8 @@ int CLIENT_STATE::reset_project(PROJECT* project) {
}
}
// if we're in the middle of a scheduler op to the project, abort it
//
if (scheduler_op->state != SCHEDULER_OP_STATE_IDLE
&& scheduler_op->project == project
) {
@ -1009,6 +1006,8 @@ int CLIENT_STATE::detach_project(PROJECT* project) {
reset_project(project);
msg_printf(project, MSG_INFO, "Detaching from project");
// find project and remove it from the vector
//
for (iter = projects.begin(); iter != projects.end(); iter++) {

View File

@ -103,6 +103,10 @@ public:
int master_fetch_retry_cap, master_fetch_interval;
int sched_retry_delay_min, sched_retry_delay_max;
int pers_retry_delay_min, pers_retry_delay_max, pers_giveup;
bool activities_suspended;
bool previous_activities_suspended;
// if activities were suspended in the previous check_suspend();
// this is needed to update GUI windows after suspension and close transfers/files.
private:
bool client_state_dirty;
@ -116,10 +120,6 @@ private:
// if set, use hardwired numbers rather than running benchmarks
bool run_cpu_benchmarks;
// if set, run benchmarks on client startup
bool activities_suspended;
bool previous_activities_suspended;
// if activities were suspended in the previous check_suspend();
// this is needed to update GUI windows after suspension and close transfers/files.
int exit_after_app_start_secs;
// if nonzero, exit this many seconds after starting an app
time_t app_started;
@ -152,6 +152,7 @@ public:
int report_result_error(RESULT &res, int err_num, const char *err_msg);
// flag a result as having an error
void set_client_state_dirty(char*);
int reset_project(PROJECT*);
private:
int link_app(PROJECT*, APP*);
int link_file_info(PROJECT*, FILE_INFO*);
@ -162,12 +163,12 @@ private:
void print_summary();
bool garbage_collect();
bool update_results();
int reset_project(PROJECT*);
// --------------- cs_account.C:
public:
int add_project(char* master_url, char* authenticator);
private:
int parse_account_files();
int add_project(char* master_url, char* authenticator);
// --------------- cs_apps.C:
public:

View File

@ -173,12 +173,12 @@ int GLOBAL_PREFS::parse(FILE* in, char* host_venue) {
}
if (strlen(host_venue)) {
if (found_venue) {
msg_printf(NULL, MSG_INFO, "General preferences: using preferences for venue %s\n", host_venue);
msg_printf(NULL, MSG_INFO, "Using preferences for '%s'\n", host_venue);
} else {
msg_printf(NULL, MSG_INFO, "General preferences: can't find special preferences for %s; using your default preferences\n", host_venue);
msg_printf(NULL, MSG_INFO, "No preferences for '%s'; using default preferences\n", host_venue);
}
} else {
msg_printf(NULL, MSG_INFO, "General preferences: no venue given; using your default general preferences\n");
msg_printf(NULL, MSG_INFO, "Using default preferences\n");
}
return 0;
}

View File

@ -345,14 +345,18 @@ bool SCHEDULER_OP::poll() {
gstate.set_client_state_dirty("master URL fetch done");
http_ops->remove(&http_op);
if (http_op.http_op_retval == 0) {
scope_messages.printf("SCHEDULER_OP::poll(): Got master file from %s; parsing\n",
project->master_url);
scope_messages.printf(
"SCHEDULER_OP::poll(): Got master file from %s; parsing\n",
project->master_url
);
retval = parse_master_file(urls);
if (retval) {
// master file parse failed.
//
if (project->tentative) {
project_add_failed(project);
PROJECT* project_temp = project;
project = 0; // keep detach(0) from removing HTTP OP
project_add_failed(project_temp);
err = true;
} else {
project->master_fetch_failures++;
@ -380,7 +384,7 @@ bool SCHEDULER_OP::poll() {
// If don't have any schedulers for this project,
// it may be the wrong URL. notify the user
//
if (project->scheduler_urls.size() == 0 && !err) {
if (!err && project->scheduler_urls.size() == 0) {
if (project->tentative) {
project_add_failed(project);
} else {

View File

@ -33,7 +33,6 @@
#include "filesys.h"
#include "log_flags.h"
#include "client_state.h"
#include "account.h"
#include "error_numbers.h"
#include "resource.h"
#include "util.h"