Commit df70da03 authored by Éric Thiébaut's avatar Éric Thiébaut
Browse files

Manage to distinguish timeouts and overwrite errors in tao_remote_mirror_fetch_data

parent 2fdb5ef7
......@@ -370,39 +370,18 @@ tao_status tao_remote_mirror_fetch_data(
tao_store_error(__func__, TAO_BAD_SIZE);
return TAO_ERROR;
}
size_t nbytes = obj->nacts*sizeof(double);
if (serial < 1) {
if (serial != 0) {
tao_store_error(__func__, TAO_BAD_SERIAL);
return TAO_ERROR;
}
if (info != NULL) {
memset(info, 0, sizeof(*info));
}
if (vals_0 != NULL) {
memset(vals_0, 0, nbytes);
}
if (vals_1 != NULL) {
memset(vals_1, 0, nbytes);
}
if (vals_2 != NULL) {
memset(vals_2, 0, nbytes);
}
if (vals_3 != NULL) {
memset(vals_3, 0, nbytes);
}
} else {
// FIXME: check whether serial is too high, server is running, etc.
double* data;
const tao_dataframe_header* header = fetch_frame(obj, serial, &data);
if (atomic_load(&header->serial) != serial) {
if (info != NULL) {
info->serial = 0;
info->mark = 0;
info->time = TAO_UNKNOWN_TIME;
}
return TAO_TIMEOUT;
}
tao_store_error(__func__, TAO_BAD_SERIAL);
return TAO_ERROR;
}
// Fetch the data.
size_t nbytes = obj->nacts*sizeof(double);
double* data;
const tao_dataframe_header* header = fetch_frame(obj, serial, &data);
tao_serial frame_serial = atomic_load(&header->serial);
if (frame_serial == serial) {
// Copy the contents of the data-frame now.
if (info != NULL) {
info->serial = serial;
info->mark = header->mark;
......@@ -420,17 +399,35 @@ tao_status tao_remote_mirror_fetch_data(
if (vals_3 != NULL) {
memcpy(vals_3, data + 3*obj->nacts, nbytes);
}
if (atomic_load(&header->serial) != serial) {
// FIXME: This is an overwrite error!
if (info != NULL) {
info->serial = -1;
info->mark = -1;
info->time = TAO_UNKNOWN_TIME;
}
return TAO_TIMEOUT;
// Check that data-frame has not been overwritten in the mean time.
frame_serial = atomic_load(&header->serial);
if (frame_serial == serial) {
return TAO_OK;
}
frame_serial = -1; // data has been overwritten
} else {
frame_serial = (frame_serial < serial ? 0 : -1);
}
// The requested frame is either to new (timeout) or too old (overwrite).
if (info != NULL) {
info->serial = frame_serial;
info->mark = 0;
info->time = TAO_UNKNOWN_TIME;
}
if (vals_0 != NULL) {
memset(vals_0, 0, nbytes);
}
if (vals_1 != NULL) {
memset(vals_1, 0, nbytes);
}
if (vals_2 != NULL) {
memset(vals_2, 0, nbytes);
}
if (vals_3 != NULL) {
memset(vals_3, 0, nbytes);
}
return TAO_OK;
return TAO_TIMEOUT;
}
tao_status tao_remote_mirror_run_loop(
......
......@@ -862,7 +862,14 @@ extern tao_serial tao_remote_mirror_wait_output(
*
* @return @ref TAO_OK on success, @ref TAO_TIMEOUT if the data-frame gets
* overwritten before its contents is copied, or @ref TAO_ERROR in case
* of failure.
* of failure. If @ref TAO_ERROR is returned, no output buffer is
* modified. If @ref TAO_TIMEOUT is returned, all output buffers are
* zero-filled and, if `info` is not `NULL`, `info->serial` is set to 0
* to indicate that the requested frame is too new (true timeout) and
* to -1 to indicate that the requested frame is too old (its contents
* has been overwritten by a newer one). It is recommeneded to always
* specify a non-`NULL` valid address for `info` and check that
* `info->serial = serial` on return.
*/
extern tao_status tao_remote_mirror_fetch_data(
const tao_remote_mirror* obj,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment