client request app quit on exit

svn path=/trunk/boinc/; revision=1053
This commit is contained in:
Eric Heien 2003-03-11 22:18:01 +00:00
parent c52bea0a20
commit 098073dfa6
12 changed files with 102 additions and 21 deletions

View File

@ -78,7 +78,7 @@ void file_append(FILE* in, MFILE &out, int skip, int filenum) {
boinc_checkpoint_completed();
}
if (run_slow) boinc_sleep(1);
if (run_slow) boinc_sleep(1.);
}
}

View File

@ -201,7 +201,7 @@ int main(int argc, char **argv) {
}
if (run_slow) {
boinc_sleep(1);
boinc_sleep(1.);
}
#ifdef SIGNAL_H

View File

@ -3767,3 +3767,22 @@ Seth March 10, 2003
client/win/
wingui_sswindow.cpp,h
wingui_mainwindow.cpp,h
Eric March 11, 2003
- changed client exit to send a quit request to the apps, wait 1
second for them to quit, then kill them if they're still open.
This allows applications to do a final checkpoint before
quitting, rather than lose their recent work
- changed boinc_sleep to accept fractional sleep values
apps/
concat.C
upper_case.C
client/
app.C,h
client_state.C
cs_apps.C
test_*.C
lib/
util.C,h

View File

@ -382,6 +382,25 @@ int ACTIVE_TASK::kill_task() {
#endif
}
bool ACTIVE_TASK::task_exited() {
#ifdef _WIN32
unsigned long exit_code;
if (GetExitCodeProcess(pid_handle, &exit_code)) {
if (exit_code != STILL_ACTIVE) {
return true;
}
}
#else
int my_pid, stat;
my_pid = wait4(pid, &stat, WNOHANG, NULL);
if (my_pid == pid) {
return true;
}
#endif
return false;
}
// Inserts an active task into the ACTIVE_TASK_SET and starts it up
//
int ACTIVE_TASK_SET::insert(ACTIVE_TASK* atp) {
@ -546,6 +565,33 @@ bool ACTIVE_TASK::read_stderr_file() {
return false;
}
// Wait up to wait_time seconds for all processes in this set to exit
//
int ACTIVE_TASK_SET::wait_for_exit(double wait_time) {
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 (!atp->task_exited()) {
all_exited = false;
break;
}
}
if (all_exited) {
return 0;
}
}
return -1;
}
// Find the ACTIVE_TASK in the current set with the matching PID
//
ACTIVE_TASK* ACTIVE_TASK_SET::lookup_pid(int pid) {
@ -587,17 +633,28 @@ void ACTIVE_TASK_SET::unsuspend_all() {
// initiate exit of all currently running tasks
//
void ACTIVE_TASK_SET::exit_tasks() {
void ACTIVE_TASK_SET::request_tasks_exit() {
unsigned int i;
ACTIVE_TASK *atp;
for (i=0; i<active_tasks.size(); i++) {
atp = active_tasks[i];
if(atp->request_exit()) {
fprintf(stderr, "ACTIVE_TASK_SET::exit_tasks(): could not suspend active_task\n");
fprintf(stderr, "ACTIVE_TASK_SET::request_tasks_exit(): could not exit active_task\n");
}
}
}
// Kills all currently running tasks without warning
//
void ACTIVE_TASK_SET::kill_tasks() {
unsigned int i;
ACTIVE_TASK *atp;
for (i=0; i<active_tasks.size(); i++) {
atp = active_tasks[i];
atp->kill_task();
}
}
// suspend a task
//
int ACTIVE_TASK::suspend() {

View File

@ -90,6 +90,8 @@ public:
// ask a task to pause. doesn't wait for it to do so.
int kill_task();
// externally kill the task. doesn't wait for exit
bool task_exited();
// return true if this task has exited
int abort();
// kill, and flag as abort pending
@ -109,13 +111,15 @@ public:
vector<ACTIVE_TASK*> active_tasks;
int insert(ACTIVE_TASK*);
int remove(ACTIVE_TASK*);
int wait_for_exit(double);
ACTIVE_TASK* lookup_pid(int);
bool poll();
bool poll_time();
void suspend_all();
void unsuspend_all();
int restart_tasks();
void exit_tasks();
void request_tasks_exit();
void kill_tasks();
int get_free_slot(int total_slots);
int write(FILE*);

View File

@ -412,7 +412,7 @@ static void print_log(char* p) {
int CLIENT_STATE::net_sleep(double x) {
if (activities_suspended) {
boinc_sleep((int)x);
boinc_sleep(x);
return 0;
} else {
return net_xfers->net_sleep(x);

View File

@ -59,15 +59,15 @@ int CLIENT_STATE::cleanup_and_exit() {
}
int CLIENT_STATE::exit_tasks() {
active_tasks.exit_tasks();
// Send a request to the tasks to exit
active_tasks.request_tasks_exit();
// Wait a second for them to exit normally
active_tasks.wait_for_exit(1);
// And then just kill them
active_tasks.kill_tasks();
// for now just kill them
unsigned int i;
ACTIVE_TASK *atp;
for (i=0; i<active_tasks.active_tasks.size(); i++) {
atp = active_tasks.active_tasks[i];
atp->kill_task();
}
return 0;
}

View File

@ -116,7 +116,7 @@ int main() {
fx2 = 0;
}
if (!fx1 && !fx2) break;
boinc_sleep(1);
boinc_sleep(1.);
}
printf("all done\n");
}

View File

@ -89,7 +89,7 @@ int main() {
op3 = 0;
}
if (!op1 && !op2 && !op3) break;
boinc_sleep(1);
boinc_sleep(1.);
}
printf("all done\n");

View File

@ -91,7 +91,7 @@ int main() {
if (nxp->io_done) break;
}
if (nxp->io_done) break;
boinc_sleep(1);
boinc_sleep(1.);
}
nxs.remove(nxp);
if (nxp->file) {

View File

@ -124,11 +124,12 @@ double dtime() {
// sleep for a specified number of seconds
//
void boinc_sleep(int seconds) {
void boinc_sleep(double seconds) {
#ifdef _WIN32
::Sleep(1000*seconds);
::Sleep((int)(1000*seconds));
#else
sleep(seconds);
sleep((int)seconds);
usleep((int)fmod(seconds*1000000,1000000));
#endif
}

View File

@ -21,7 +21,7 @@
extern int double_to_ydhms (double x, int smallest_timescale, char *buf);
extern double dtime();
extern void boinc_sleep( int seconds );
extern void boinc_sleep(double);
extern int parse_command_line( char *, char ** );
extern int lock_file(char*);
extern double drand();