diff --git a/checkin_notes b/checkin_notes
index 1909a8c3f2..3ec72ddbc3 100755
--- a/checkin_notes
+++ b/checkin_notes
@@ -16692,3 +16692,16 @@ Rom 24 Aug 2004
- Tag for 4.04 release, all platforms
boinc_release_4_04
+David 24 Aug 2004
+ - Core client: check that shared memory exists before
+ attempting to send or get msgs to an app.
+ This hopefully will fix a crashing bug
+ that happens when you use quit-on-suspend
+ (since the shared-memory seg is deleted on quit)
+ - Separate get_app_status_msg() and get_trickle_up_msg() functions
+
+ client/
+ app.h
+ app_control.C
+ app_graphics.C
+
diff --git a/client/app.h b/client/app.h
index b774cdaca4..f68c39b39e 100644
--- a/client/app.h
+++ b/client/app.h
@@ -165,7 +165,8 @@ public:
bool check_max_mem_exceeded();
void estimate_frac_rate_of_change(double);
- bool get_msg();
+ bool get_app_status_msg();
+ bool get_trickle_up_msg();
double est_time_to_completion();
bool read_stderr_file();
bool finish_file_present();
diff --git a/client/app_control.C b/client/app_control.C
index 1ed4f32c86..9fa6f2d844 100644
--- a/client/app_control.C
+++ b/client/app_control.C
@@ -66,6 +66,7 @@ bool ACTIVE_TASK::process_exists() {
// Send a quit message.
//
int ACTIVE_TASK::request_exit() {
+ if (!app_client_shm.shm) return 1;
app_client_shm.shm->process_control_request.send_msg_overwrite("");
return 0;
}
@@ -180,7 +181,8 @@ int ACTIVE_TASK::preempt(bool quit_task) {
//
#ifdef _WIN32
bool ACTIVE_TASK::handle_exited_app(unsigned long exit_code) {
- get_msg();
+ get_app_status_msg();
+ get_trickle_up_msg();
result->final_cpu_time = checkpoint_cpu_time;
if (state == PROCESS_ABORT_PENDING) {
state = PROCESS_ABORTED;
@@ -223,7 +225,8 @@ bool ACTIVE_TASK::handle_exited_app(unsigned long exit_code) {
bool ACTIVE_TASK::handle_exited_app(int stat, struct rusage rs) {
SCOPE_MSG_LOG scope_messages(log_messages, CLIENT_MSG_LOG::DEBUG_TASK);
- get_msg();
+ get_app_status_msg();
+ get_trickle_up_msg();
result->final_cpu_time = checkpoint_cpu_time;
if (state == PROCESS_ABORT_PENDING) {
state = PROCESS_ABORTED;
@@ -325,6 +328,7 @@ void ACTIVE_TASK_SET::send_trickle_downs() {
atp = active_tasks[i];
if (!atp->process_exists()) continue;
if (atp->have_trickle_down) {
+ if (!atp->app_client_shm.shm) continue;
sent = atp->app_client_shm.shm->trickle_down.send_msg("\n");
if (sent) atp->have_trickle_down = false;
}
@@ -338,6 +342,7 @@ void ACTIVE_TASK_SET::send_heartbeats() {
for (i=0; iprocess_exists()) continue;
+ if (!atp->app_client_shm.shm) continue;
atp->app_client_shm.shm->heartbeat.send_msg("\n");
}
}
@@ -550,6 +555,7 @@ int ACTIVE_TASK::request_reread_prefs() {
retval = write_app_init_file(aid);
if (retval) return retval;
+ if (!app_client_shm.shm) return 0;
app_client_shm.shm->graphics_request.send_msg(
xml_graphics_modes[MODE_REREAD_PREFS]
);
@@ -757,6 +763,7 @@ void ACTIVE_TASK_SET::kill_tasks(PROJECT* proj) {
// suspend a task
//
int ACTIVE_TASK::suspend() {
+ if (!app_client_shm.shm) return 0;
app_client_shm.shm->process_control_request.send_msg_overwrite("");
state = PROCESS_SUSPENDED;
return 0;
@@ -765,6 +772,7 @@ int ACTIVE_TASK::suspend() {
// resume a suspended task
//
int ACTIVE_TASK::unsuspend() {
+ if (!app_client_shm.shm) return 0;
app_client_shm.shm->process_control_request.send_msg_overwrite("");
state = PROCESS_EXECUTING;
return 0;
@@ -774,11 +782,11 @@ int ACTIVE_TASK::unsuspend() {
// (with CPU done, frac done etc.)
// If so parse it and return true.
//
-bool ACTIVE_TASK::get_msg() {
+bool ACTIVE_TASK::get_app_status_msg() {
char msg_buf[MSG_CHANNEL_SIZE];
bool found = false;
- int retval;
+ if (!app_client_shm.shm) return false;
if (app_client_shm.shm->app_status.get_msg(msg_buf)) {
fraction_done = current_cpu_time = checkpoint_cpu_time = 0.0;
parse_double(msg_buf, "", fraction_done);
@@ -788,6 +796,15 @@ bool ACTIVE_TASK::get_msg() {
parse_double(msg_buf, "", resident_set_size);
found = true;
}
+ return found;
+}
+
+bool ACTIVE_TASK::get_trickle_up_msg() {
+ char msg_buf[MSG_CHANNEL_SIZE];
+ bool found = false;
+ int retval;
+
+ if (!app_client_shm.shm) return false;
if (app_client_shm.shm->trickle_up.get_msg(msg_buf)) {
if (match_tag(msg_buf, "")) {
retval = move_trickle_file();
@@ -814,12 +831,13 @@ bool ACTIVE_TASK_SET::get_msgs() {
atp = active_tasks[i];
if (!atp->process_exists()) continue;
old_time = atp->checkpoint_cpu_time;
- if (atp->get_msg()) {
+ if (atp->get_app_status_msg()) {
atp->estimate_frac_rate_of_change(now);
if (old_time != atp->checkpoint_cpu_time) {
action = true;
}
}
+ atp->get_trickle_up_msg();
}
return action;
}
diff --git a/client/app_graphics.C b/client/app_graphics.C
index df81cbfa97..e6701f3fe2 100644
--- a/client/app_graphics.C
+++ b/client/app_graphics.C
@@ -36,6 +36,7 @@ void ACTIVE_TASK::request_graphics_mode(int mode) {
}
bool ACTIVE_TASK::send_graphics_mode(int mode) {
+ if (!app_client_shm.shm) return false;
bool sent = app_client_shm.shm->graphics_request.send_msg(
xml_graphics_modes[mode]
);
@@ -46,6 +47,8 @@ bool ACTIVE_TASK::send_graphics_mode(int mode) {
void ACTIVE_TASK::check_graphics_mode_ack() {
int mode;
char buf[MSG_CHANNEL_SIZE];
+
+ if (!app_client_shm.shm) return;
if (app_client_shm.shm->graphics_reply.get_msg(buf)) {
mode = app_client_shm.decode_graphics_msg(buf);
//msg_printf(NULL, MSG_INFO, "got graphics ack %d", mode);
diff --git a/doc/cpid.php b/doc/cpid.php
index ea026a9cc1..b4b2d336e7 100644
--- a/doc/cpid.php
+++ b/doc/cpid.php
@@ -29,10 +29,10 @@ when it's created; it's a long random string.
When a scheduling server replies to an RPC,
it includes the account's CPID and hashed email address.
-The core client stores the CPID and hashed email address
+The BOINC client stores the CPID and hashed email address
of each account to which it's attached.
-When the core client makes an RPC request to a scheduling server,
+When the BOINC client makes an RPC request to a scheduling server,
it includes the greatest (in terms of string comparison) CPID
from among projects with the same hashed email.