let apps handle abort requests

svn path=/trunk/boinc/; revision=9400
This commit is contained in:
David Anderson 2006-02-03 20:48:48 +00:00
parent f526752804
commit c3425dbb6c
6 changed files with 74 additions and 14 deletions

View File

@ -262,6 +262,7 @@ int boinc_init_options_general(BOINC_OPTIONS& opt) {
boinc_status.no_heartbeat = false;
boinc_status.suspended = false;
boinc_status.quit_request = false;
boinc_status.abort_request = false;
if (options.main_program) {
// make sure we're the only app running in this slot
@ -309,10 +310,11 @@ int boinc_init_options_general(BOINC_OPTIONS& opt) {
return 0;
}
int boinc_get_status(BOINC_STATUS& s) {
s.no_heartbeat = boinc_status.no_heartbeat;
s.suspended = boinc_status.suspended;
s.quit_request = boinc_status.quit_request;
int boinc_get_status(BOINC_STATUS *s) {
s->no_heartbeat = boinc_status.no_heartbeat;
s->suspended = boinc_status.suspended;
s->quit_request = boinc_status.quit_request;
s->abort_request = boinc_status.abort_request;
return 0;
}
@ -576,6 +578,12 @@ static void handle_process_control_msg() {
boinc_exit(0);
}
}
if (match_tag(buf, "<abort/>")) {
boinc_status.abort_request = true;
if (options.direct_process_action) {
boinc_exit(0);
}
}
if (match_tag(buf, "<reread_app_info/>")) {
boinc_status.reread_init_data_file = true;
}

View File

@ -56,6 +56,7 @@ struct BOINC_STATUS {
int suspended;
int quit_request;
int reread_init_data_file;
int abort_request;
};
extern int boinc_init(void);
@ -98,7 +99,7 @@ extern int setMacIcon(char *filename, char *iconData, long iconSize);
#include "app_ipc.h"
extern int boinc_init_options(BOINC_OPTIONS&);
extern int boinc_get_status(BOINC_STATUS&);
extern int boinc_get_status(BOINC_STATUS*);
extern int boinc_resolve_filename_s(const char*, std::string&);
extern int boinc_get_init_data(APP_INIT_DATA&);
extern int boinc_wu_cpu_time(double&);

View File

@ -1444,3 +1444,30 @@ David 2 Feb 2005
client/
cs_apps.C
David 3 Feb 2005
- Allow apps to do cleanup when they're aborted.
- Add abort_request to BOINC_STATUS structure
- API library: handle <abort/> message
- Change boinc_get_status() arg from reference
to pointer (for easier FORTRAN interface).
This is an API change, but I think only CPDN uses this.
- ACTIVE_TASK_SET::poll():
Check for processes that are ABORT_PENDING
for more than 5 seconds, and kill them
From Carl Christensen, somewhat modified.
I changed the way tasks are aborted.
The core client can't sleep; that locks up the UI.
So we can't sleep 5 seconds waiting for an app to exit
after sending it an <abort/> message
(existing apps don't recognize this message).
Instead, send it the <abort/> message,
set its state to PROCESS_ABORT_PENDING,
and check it from the polling loop 5 seconds later.
api/
boinc_api.C,h
client/
app.C,h
app_control.C

View File

@ -194,7 +194,7 @@ void ACTIVE_TASK_SET::free_mem() {
}
#endif
// Do period checks on running apps:
// Do periodic checks on running apps:
// - get latest CPU time and % done info
// - check if any has exited, and clean up
// - see if any has exceeded its CPU or disk space limits, and abort it
@ -211,9 +211,16 @@ bool ACTIVE_TASK_SET::poll() {
graphics_poll();
process_control_poll();
action |= check_rsc_limits_exceeded();
if (get_msgs()) {
action = true;
action |= get_msgs();
for (unsigned int i=0; i<active_tasks.size(); i++) {
ACTIVE_TASK* atp = active_tasks[i];
if (atp->task_state == PROCESS_ABORT_PENDING) {
if (gstate.now > atp->abort_time + 5.0) {
atp->kill_task();
}
}
}
if (action) {
gstate.set_client_state_dirty("ACTIVE_TASK_SET::poll");
}

View File

@ -126,6 +126,8 @@ public:
int want_network;
// This task wants to do network comm (for F@h)
// this is passed via share-memory message (app_status channel)
double abort_time; // when we sent an abort message to this app
// kill it 5 seconds later if it doesn't exit
APP_CLIENT_SHM app_client_shm; // core/app shared mem
MSG_QUEUE graphics_request_queue;
@ -154,6 +156,7 @@ public:
int request_exit();
// ask the process to exit gracefully,
// i.e. by sending a <quit> message
int request_abort(); // send "abort" message
bool process_exists();
int kill_task();
// Kill process forcibly,

View File

@ -77,14 +77,24 @@ bool ACTIVE_TASK::process_exists() {
int ACTIVE_TASK::request_exit() {
if (!app_client_shm.shm) return 1;
process_control_queue.msg_queue_send(
"<quit/>",
"<quit/>",
app_client_shm.shm->process_control_request
);
return 0;
}
// send a kill signal.
// This is not caught by the process
// Send an abort message.
//
int ACTIVE_TASK::request_abort() {
if (!app_client_shm.shm) return 1;
process_control_queue.msg_queue_send(
"<abort/>",
app_client_shm.shm->process_control_request
);
return 0;
}
// Kill the task by OS-specific means.
//
int ACTIVE_TASK::kill_task() {
#ifdef _WIN32
@ -529,13 +539,17 @@ bool ACTIVE_TASK_SET::check_rsc_limits_exceeded() {
return did_anything;
}
// If process is running, send it a kill signal
// This is done when app has exceeded CPU, disk, or mem limits
// If process is running, send it an "abort" message,
// and if it doesn't exit within 5 seconds,
// kill it by OS-specific mechanism (e.g. KILL signal).
// This is done when app has exceeded CPU, disk, or mem limits,
// or when the user has requested it.
//
int ACTIVE_TASK::abort_task(int exit_status, const char* msg) {
if (task_state == PROCESS_EXECUTING || task_state == PROCESS_SUSPENDED) {
task_state = PROCESS_ABORT_PENDING;
kill_task();
abort_time = gstate.now;
request_abort();
} else {
task_state = PROCESS_ABORTED;
}