mirror of https://github.com/BOINC/boinc.git
*** empty log message ***
svn path=/trunk/boinc/; revision=2506
This commit is contained in:
parent
976b549a24
commit
0790b9b2aa
|
@ -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
|
||||
|
|
53
client/app.C
53
client/app.C
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue