From 098073dfa675f1ea2ba6d3d6ea144afe1121a3d0 Mon Sep 17 00:00:00 2001 From: Eric Heien Date: Tue, 11 Mar 2003 22:18:01 +0000 Subject: [PATCH] client request app quit on exit svn path=/trunk/boinc/; revision=1053 --- apps/concat.C | 2 +- apps/upper_case.C | 2 +- checkin_notes | 19 +++++++++++++ client/app.C | 61 +++++++++++++++++++++++++++++++++++++++-- client/app.h | 6 +++- client/client_state.C | 2 +- client/cs_apps.C | 16 +++++------ client/test_file_xfer.C | 2 +- client/test_http.C | 2 +- client/test_net_xfer.C | 2 +- lib/util.C | 7 +++-- lib/util.h | 2 +- 12 files changed, 102 insertions(+), 21 deletions(-) diff --git a/apps/concat.C b/apps/concat.C index 3028bf35ce..edf37b7e58 100644 --- a/apps/concat.C +++ b/apps/concat.C @@ -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.); } } diff --git a/apps/upper_case.C b/apps/upper_case.C index 94ff413ad0..da1e222b09 100755 --- a/apps/upper_case.C +++ b/apps/upper_case.C @@ -201,7 +201,7 @@ int main(int argc, char **argv) { } if (run_slow) { - boinc_sleep(1); + boinc_sleep(1.); } #ifdef SIGNAL_H diff --git a/checkin_notes b/checkin_notes index 3c84e4b8c9..b5e82dab13 100755 --- a/checkin_notes +++ b/checkin_notes @@ -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 + diff --git a/client/app.C b/client/app.C index e8122b9ca0..768e4b1a0f 100644 --- a/client/app.C +++ b/client/app.C @@ -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;ntask_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; irequest_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; ikill_task(); + } +} + // suspend a task // int ACTIVE_TASK::suspend() { diff --git a/client/app.h b/client/app.h index 03c3faae24..002a671bb3 100644 --- a/client/app.h +++ b/client/app.h @@ -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_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*); diff --git a/client/client_state.C b/client/client_state.C index fe6de94419..dfca83b851 100644 --- a/client/client_state.C +++ b/client/client_state.C @@ -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); diff --git a/client/cs_apps.C b/client/cs_apps.C index 3db232343a..63e6ba18dc 100644 --- a/client/cs_apps.C +++ b/client/cs_apps.C @@ -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; ikill_task(); - } return 0; } diff --git a/client/test_file_xfer.C b/client/test_file_xfer.C index bbbd997ed7..feef692c16 100644 --- a/client/test_file_xfer.C +++ b/client/test_file_xfer.C @@ -116,7 +116,7 @@ int main() { fx2 = 0; } if (!fx1 && !fx2) break; - boinc_sleep(1); + boinc_sleep(1.); } printf("all done\n"); } diff --git a/client/test_http.C b/client/test_http.C index 210b5576ed..b41ff7ffe7 100644 --- a/client/test_http.C +++ b/client/test_http.C @@ -89,7 +89,7 @@ int main() { op3 = 0; } if (!op1 && !op2 && !op3) break; - boinc_sleep(1); + boinc_sleep(1.); } printf("all done\n"); diff --git a/client/test_net_xfer.C b/client/test_net_xfer.C index 07416af1a2..90ce3a2c8d 100644 --- a/client/test_net_xfer.C +++ b/client/test_net_xfer.C @@ -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) { diff --git a/lib/util.C b/lib/util.C index dc74afb046..39f94e9247 100755 --- a/lib/util.C +++ b/lib/util.C @@ -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 } diff --git a/lib/util.h b/lib/util.h index 41461158d9..5cfbde439d 100755 --- a/lib/util.h +++ b/lib/util.h @@ -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();