mirror of https://github.com/BOINC/boinc.git
let apps handle abort requests
svn path=/trunk/boinc/; revision=9400
This commit is contained in:
parent
f526752804
commit
c3425dbb6c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -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
|
||||
|
|
13
client/app.C
13
client/app.C
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue