API: fix bug where app doesn't exit if client dies while app in critical section

There were two parts to this:
- In the timer thread, we need to check for client death even if
  we're in a critical section.
  If both conditions hold, set the no_heartbeat status flag.
- In boinc_end_critical_section(), check no_heartbeat and exit if set.

Also: the various checks in boinc_end_critical_section()
(quit, abort, no heartbeat) should be conditioned on
options.direct_process_action.
Otherwise wrappers that use critical sections won't do the right thing.
This commit is contained in:
David Anderson 2014-10-31 10:37:56 -07:00
parent 5f36375e2c
commit f0c39bdf51
2 changed files with 13 additions and 8 deletions

View File

@ -1179,18 +1179,19 @@ static void timer_handler() {
// see if the client has died, which means we need to die too
// (unless we're in a critical section)
//
if (in_critical_section==0 && options.check_heartbeat) {
if (options.check_heartbeat) {
if (client_dead()) {
fprintf(stderr, "%s timer handler: client dead, exiting\n",
boinc_msg_prefix(buf, sizeof(buf))
);
if (options.direct_process_action) {
if (options.direct_process_action && !in_critical_section) {
exit_from_timer_thread(0);
} else {
boinc_status.no_heartbeat = true;
}
}
}
// don't bother reporting CPU time etc. if we're suspended
//
if (options.send_status_msgs && !boinc_status.suspended) {
@ -1428,13 +1429,16 @@ void boinc_end_critical_section() {
// See if we got suspend/quit/abort while in critical section,
// and handle them here.
//
if (boinc_status.quit_request) {
boinc_exit(0);
}
if (boinc_status.abort_request) {
boinc_exit(EXIT_ABORTED_BY_CLIENT);
}
if (options.direct_process_action) {
if (boinc_status.no_heartbeat) {
boinc_exit(0);
}
if (boinc_status.quit_request) {
boinc_exit(0);
}
if (boinc_status.abort_request) {
boinc_exit(EXIT_ABORTED_BY_CLIENT);
}
acquire_mutex();
if (suspend_request) {
suspend_request = false;

View File

@ -56,6 +56,7 @@ typedef struct BOINC_OPTIONS {
// if heartbeat fail, or get process control msg, take
// direction action (exit, suspend, resume).
// Otherwise just set flag in BOINC status
// This is true for regular apps, false for wrappers
int multi_thread;
// set this if application creates threads in main process
int multi_process;