mirror of https://github.com/BOINC/boinc.git
client request app quit on exit
svn path=/trunk/boinc/; revision=1053
This commit is contained in:
parent
c52bea0a20
commit
098073dfa6
|
@ -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.);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -201,7 +201,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
if (run_slow) {
|
||||
boinc_sleep(1);
|
||||
boinc_sleep(1.);
|
||||
}
|
||||
|
||||
#ifdef SIGNAL_H
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
61
client/app.C
61
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;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() {
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ int main() {
|
|||
fx2 = 0;
|
||||
}
|
||||
if (!fx1 && !fx2) break;
|
||||
boinc_sleep(1);
|
||||
boinc_sleep(1.);
|
||||
}
|
||||
printf("all done\n");
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ int main() {
|
|||
op3 = 0;
|
||||
}
|
||||
if (!op1 && !op2 && !op3) break;
|
||||
boinc_sleep(1);
|
||||
boinc_sleep(1.);
|
||||
}
|
||||
printf("all done\n");
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue