#include "cms.hh"
#include "cmsdiag.hh"
#include "rcs_print.hh"
#include "physmem.hh"
int cms_print_queue_free_space = 0;
int cms_print_queue_full_messages = 1;
CMS_STATUS CMS::internal_access(void *_global, long _global_size,
void *_local, int *serial_number)
{
if (NULL == _global) {
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (NULL == dummy_handle) {
dummy_handle = new PHYSMEM_HANDLE;
}
if (NULL == dummy_handle) {
rcs_print_error("CMS: Couldn't create PHYSMEM_HANDLE.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
dummy_handle->set_to_ptr(_global, _global_size);
internal_access(dummy_handle, _local, serial_number);
return (status);
}
CMS_STATUS CMS::internal_access(PHYSMEM_HANDLE * _global, void *_local, int *serial_number)
{
status = CMS_STATUS_NOT_SET;
if (NULL == _global) {
rcs_print_error("CMS: Handle to global memory is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data = _global;
if (CMS_CLEAR_ACCESS == internal_access_type) {
internal_clear();
return (status);
}
if (min_compatible_version > 2.58 || min_compatible_version < 1E-6) {
handle_to_global_data->offset += skip_area;
}
if (CMS_GET_DIAG_INFO_ACCESS == internal_access_type) {
internal_retrieve_diag_info(handle_to_global_data, _local);
return (status);
}
long orig_offset = handle_to_global_data->offset;
if (enable_diagnostics) {
handle_to_global_data->offset +=
sizeof(CMS_DIAG_HEADER) +
total_connections * sizeof(CMS_DIAG_PROC_INFO);
handle_to_global_data->enable_byte_counting = 1;
pre_op_total_bytes_moved = handle_to_global_data->total_bytes_moved;
}
char was_read_byte;
write_just_completed = 0;
int read_only = ((internal_access_type == CMS_CHECK_IF_READ_ACCESS) ||
(internal_access_type == CMS_READ_ACCESS) ||
(internal_access_type == CMS_PEEK_ACCESS));
long offset_before_split = handle_to_global_data->offset;
if (total_subdivisions >= 1 && current_subdivision > 0
&& current_subdivision < total_subdivisions) {
handle_to_global_data->offset += (current_subdivision * subdiv_size);
handle_to_global_data->size =
((current_subdivision + 1) * subdiv_size);
if (handle_to_global_data->size > size) {
handle_to_global_data->size = size;
}
}
if (split_buffer) {
if (internal_access_type == CMS_WRITE_IF_READ_ACCESS) {
handle_to_global_data->offset++;
handle_to_global_data->read(&was_read_byte, 1);
handle_to_global_data->offset--;
header.was_read = (was_read_byte == toggle_bit + 1);
if (!header.was_read) {
status = CMS_WRITE_WAS_BLOCKED;
return (status);
}
internal_access_type = CMS_WRITE_ACCESS;
}
if (read_only == toggle_bit) {
handle_to_global_data->offset += 2;
handle_to_global_data->size = half_size;
} else {
handle_to_global_data->offset += half_offset;
handle_to_global_data->size = size;
}
}
if (!queuing_enabled) {
if (neutral) {
switch (internal_access_type) {
case CMS_CHECK_IF_READ_ACCESS:
check_if_read_encoded();
break;
case CMS_READ_ACCESS:
read_encoded();
break;
case CMS_PEEK_ACCESS:
peek_encoded();
break;
case CMS_WRITE_ACCESS:
write_encoded();
break;
case CMS_WRITE_IF_READ_ACCESS:
write_if_read_encoded();
break;
case CMS_GET_MSG_COUNT_ACCESS:
get_msg_count_encoded();
break;
default:
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
} else {
switch (internal_access_type) {
case CMS_CHECK_IF_READ_ACCESS:
check_if_read_raw();
break;
case CMS_READ_ACCESS:
read_raw();
break;
case CMS_PEEK_ACCESS:
peek_raw();
break;
case CMS_WRITE_ACCESS:
write_raw(_local, serial_number);
break;
case CMS_WRITE_IF_READ_ACCESS:
write_if_read_raw(_local, serial_number);
break;
case CMS_GET_MSG_COUNT_ACCESS:
get_msg_count_raw();
break;
default:
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
}
} else {
if (neutral) {
switch (internal_access_type) {
case CMS_CHECK_IF_READ_ACCESS:
queue_check_if_read_encoded();
break;
case CMS_READ_ACCESS:
queue_read_encoded();
break;
case CMS_PEEK_ACCESS:
queue_peek_encoded();
break;
case CMS_WRITE_ACCESS:
queue_write_encoded();
break;
case CMS_WRITE_IF_READ_ACCESS:
queue_write_if_read_encoded();
break;
case CMS_GET_QUEUE_LENGTH_ACCESS:
queue_get_queue_length_encoded();
break;
case CMS_GET_SPACE_AVAILABLE_ACCESS:
queue_get_space_available_encoded();
break;
case CMS_GET_MSG_COUNT_ACCESS:
queue_get_msg_count_encoded();
break;
default:
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
} else {
switch (internal_access_type) {
case CMS_CHECK_IF_READ_ACCESS:
queue_check_if_read_raw();
break;
case CMS_READ_ACCESS:
queue_read_raw();
break;
case CMS_PEEK_ACCESS:
queue_peek_raw();
break;
case CMS_WRITE_ACCESS:
queue_write_raw(_local, serial_number);
break;
case CMS_WRITE_IF_READ_ACCESS:
queue_write_if_read_raw(_local, serial_number);
break;
case CMS_GET_QUEUE_LENGTH_ACCESS:
queue_get_queue_length_raw();
break;
case CMS_GET_SPACE_AVAILABLE_ACCESS:
queue_get_space_available_raw();
break;
case CMS_GET_MSG_COUNT_ACCESS:
queue_get_msg_count_raw();
break;
default:
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
}
}
if (split_buffer) {
handle_to_global_data->offset = offset_before_split + 1;
if (internal_access_type == CMS_READ_ACCESS) {
was_read_byte = 1;
} else if (!read_only) {
was_read_byte = 0;
}
if (-1 == handle_to_global_data->write(&was_read_byte, 1)) {
rcs_print_error("CMS: can not set was read flag.\n");
}
}
if (enable_diagnostics) {
handle_to_global_data->offset = orig_offset;
calculate_and_store_diag_info(handle_to_global_data, _local);
}
return (status);
}
CMS_STATUS CMS::internal_clear()
{
in_buffer_id = 0;
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (-1 == handle_to_global_data->clear_memory()) {
rcs_print_error("CMS: Can't clear global_memory.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
int temp_offset = handle_to_global_data->offset;
handle_to_global_data->offset = 0;
if (-1 == handle_to_global_data->write(BufferName, 32)) {
rcs_print_error("CMS: Can't clear reset name in global memory.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data->offset = temp_offset;
return (status = CMS_CLEAR_OK);
}
int CMS::check_if_read_raw()
{
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
if (-1 == handle_to_global_data->read(&header, sizeof(CMS_HEADER))) {
rcs_print_error
("CMS: Error reading from global memory for %s at %s:%d",
BufferName, __FILE__, __LINE__);
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
return ((int) header.was_read);
}
int CMS::queue_check_if_read_raw()
{
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
if (-1 == handle_to_global_data->read(&queuing_header,
sizeof(CMS_QUEUING_HEADER))) {
rcs_print_error
("CMS: Error reading from global memory for %s at %s:%d\n",
BufferName, __FILE__, __LINE__);
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
return ((int) (queuing_header.queue_length == 0));
}
int CMS::check_if_read_encoded()
{
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
if (-1 == handle_to_global_data->read(encoded_header,
encoded_header_size)) {
rcs_print_error
("CMS: Error reading from global memory for %s at %s:%d\n",
BufferName, __FILE__, __LINE__);
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
decode_header();
return ((int) header.was_read);
}
int CMS::queue_check_if_read_encoded()
{
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
if (-1 == handle_to_global_data->read(encoded_queuing_header,
encoded_queuing_header_size)) {
rcs_print_error
("CMS: Error reading from global memory for %s at %s:%d\n",
BufferName, __FILE__, __LINE__);
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
decode_queuing_header();
return ((int) (queuing_header.queue_length == 0));
}
int CMS::get_msg_count_raw()
{
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
if (-1 == handle_to_global_data->read(&header, sizeof(CMS_HEADER))) {
rcs_print_error
("CMS: Error reading from global memory for %s at %s:%d",
BufferName, __FILE__, __LINE__);
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
return (header.write_id);
}
int CMS::queue_get_msg_count_raw()
{
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
if (-1 == handle_to_global_data->read(&queuing_header,
sizeof(CMS_QUEUING_HEADER))) {
rcs_print_error
("CMS: Error reading from global memory for %s at %s:%d\n",
BufferName, __FILE__, __LINE__);
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
return (header.write_id = queuing_header.write_id);
}
int CMS::get_msg_count_encoded()
{
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
if (-1 == handle_to_global_data->read(encoded_header,
encoded_header_size)) {
rcs_print_error
("CMS: Error reading from global memory for %s at %s:%d\n",
BufferName, __FILE__, __LINE__);
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
decode_header();
return ((int) header.write_id);
}
int CMS::queue_get_msg_count_encoded()
{
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
if (-1 == handle_to_global_data->read(encoded_queuing_header,
encoded_queuing_header_size)) {
rcs_print_error
("CMS: Error reading from global memory for %s at %s:%d\n",
BufferName, __FILE__, __LINE__);
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
decode_queuing_header();
return (header.write_id = queuing_header.write_id);
}
int CMS::queue_get_queue_length_raw()
{
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
if (-1 == handle_to_global_data->read(&queuing_header,
sizeof(CMS_QUEUING_HEADER))) {
rcs_print_error
("CMS: Error reading from global memory for %s at %s:%d\n",
BufferName, __FILE__, __LINE__);
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
return (queuing_header.queue_length);
}
int CMS::queue_get_queue_length_encoded()
{
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
if (-1 == handle_to_global_data->read(encoded_queuing_header,
encoded_queuing_header_size)) {
rcs_print_error
("CMS: Error reading from global memory for %s at %s:%d\n",
BufferName, __FILE__, __LINE__);
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
decode_queuing_header();
return (queuing_header.queue_length);
}
int CMS::queue_get_space_available_raw()
{
long queuing_header_offset;
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
queuing_header_offset = handle_to_global_data->offset;
if (-1 == handle_to_global_data->read(&queuing_header,
sizeof(CMS_QUEUING_HEADER))) {
rcs_print_error
("CMS: Error reading from global memory for %s at %s:%d\n",
BufferName, __FILE__, __LINE__);
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
if (queuing_header.tail > queuing_header.head) {
free_space = 0;
if (handle_to_global_data->size - queuing_header.tail -
queuing_header_offset > 0) {
free_space =
handle_to_global_data->size - queuing_header.tail -
queuing_header_offset;
}
if (queuing_header.head - sizeof(CMS_QUEUING_HEADER) > 0) {
free_space += queuing_header.head - sizeof(CMS_QUEUING_HEADER);
}
} else if (queuing_header.tail < queuing_header.head) {
free_space = queuing_header.head - queuing_header.tail;
}
if (queuing_header.queue_length == 0) {
free_space = handle_to_global_data->size
- sizeof(CMS_QUEUING_HEADER) - queuing_header_offset;
}
if (cms_print_queue_free_space) {
rcs_print("queue free space = %ld\n", free_space);
rcs_print(" { head=%ld,tail=%ld,end=%ld,length=%ld,id=%ld }\n",
queuing_header.head,
queuing_header.tail,
queuing_header.end_queue_space,
queuing_header.queue_length, queuing_header.write_id);
}
return (free_space);
}
int CMS::queue_get_space_available_encoded()
{
long queuing_header_offset;
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
queuing_header_offset = handle_to_global_data->offset;
if (-1 == handle_to_global_data->read(encoded_queuing_header,
encoded_queuing_header_size)) {
rcs_print_error
("CMS: Error reading from global memory for %s at %s:%d\n",
BufferName, __FILE__, __LINE__);
status = CMS_INTERNAL_ACCESS_ERROR;
return 0;
}
decode_queuing_header();
if (queuing_header.tail > queuing_header.head) {
free_space = 0;
if (handle_to_global_data->size - queuing_header.tail -
queuing_header_offset > 0) {
free_space =
handle_to_global_data->size - queuing_header.tail -
queuing_header_offset;
}
if (queuing_header.head - encoded_queuing_header_size -
queuing_header_offset > 0) {
free_space += queuing_header.head - encoded_queuing_header_size -
queuing_header_offset;
}
} else if (queuing_header.tail < queuing_header.head) {
free_space = queuing_header.head - queuing_header.tail;
}
if (queuing_header.queue_length == 0) {
free_space = handle_to_global_data->size
- encoded_queuing_header_size - queuing_header_offset;
}
if (cms_print_queue_free_space) {
rcs_print("queue free space = %ld\n", free_space);
rcs_print(" { head=%ld,tail=%ld,end=%ld,length=%ld,id=%ld }\n",
queuing_header.head,
queuing_header.tail,
queuing_header.end_queue_space,
queuing_header.queue_length, queuing_header.write_id);
}
return (free_space);
}
CMS_STATUS CMS::read_raw()
{
if (!read_permission_flag) {
rcs_print_error("CMS: %s was not configured to read %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
if (NULL == handle_to_global_data) {
rcs_print_error("CMS:(%s) handle_to_global_data is NULL.\n",
BufferName);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (-1 == handle_to_global_data->read(&header, sizeof(CMS_HEADER))) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (check_id(header.write_id) == CMS_READ_OK) {
if (header.in_buffer_size > max_message_size) {
rcs_print_error
("CMS:(%s) Message size of %ld exceeds maximum of %ld\n",
BufferName, header.in_buffer_size, max_message_size);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data->offset += sizeof(CMS_HEADER);
if (-1 ==
handle_to_global_data->read(subdiv_data,
(long) header.in_buffer_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data->offset -= sizeof(CMS_HEADER);
}
header.was_read = 1;
if (-1 == handle_to_global_data->write(&header, sizeof(CMS_HEADER))) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
return (status);
}
CMS_STATUS CMS::queue_read_raw()
{
long queuing_header_offset;
if (!read_permission_flag) {
rcs_print_error("CMS: %s was not configured to read %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
queuing_header_offset = handle_to_global_data->offset;
if (-1 == handle_to_global_data->read(&queuing_header,
sizeof(CMS_QUEUING_HEADER))) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (queuing_header.queue_length == 0) {
return (status = CMS_READ_OLD);
}
handle_to_global_data->offset += queuing_header.head;
if (-1 == handle_to_global_data->read(&header, sizeof(CMS_HEADER))) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (header.in_buffer_size > max_message_size) {
rcs_print_error
("CMS:(%s) Message size of %ld exceeds maximum of %ld\n",
BufferName, header.in_buffer_size, max_message_size);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
header.was_read = 1;
if (-1 == handle_to_global_data->write(&header, sizeof(CMS_HEADER))) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data->offset += sizeof(CMS_HEADER);
if (-1 ==
handle_to_global_data->read(subdiv_data,
(long) header.in_buffer_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
queuing_header.head += header.in_buffer_size + sizeof(CMS_HEADER);
if (queuing_header.head >= queuing_header.end_queue_space) {
queuing_header.head = sizeof(CMS_QUEUING_HEADER);
}
queuing_header.queue_length--;
if (queuing_header.queue_length == 0) {
queuing_header.head = queuing_header.tail =
sizeof(CMS_QUEUING_HEADER);
queuing_header.end_queue_space = queuing_header.tail;
}
handle_to_global_data->offset = queuing_header_offset;
if (-1 == handle_to_global_data->write(&queuing_header,
sizeof(CMS_QUEUING_HEADER))) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
check_id(header.write_id);
return (status);
}
CMS_STATUS CMS::read_encoded()
{
if (!read_permission_flag) {
rcs_print_error("CMS: %s was not configured to read %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (-1 == handle_to_global_data->read(encoded_header,
encoded_header_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
decode_header();
if (check_id(header.write_id) == CMS_READ_OK) {
if (header.in_buffer_size > max_message_size) {
rcs_print_error
("CMS:(%s) Message size of %ld exceeds maximum of %ld\n",
BufferName, header.in_buffer_size, max_message_size);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data->offset += encoded_header_size;
if (-1 == handle_to_global_data->read(encoded_data,
(long) header.in_buffer_size)) {
rcs_print_error
("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data->offset -= encoded_header_size;
}
header.was_read = 1;
encode_header();
if (-1 ==
handle_to_global_data->write(encoded_header, encoded_header_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
return (status);
}
CMS_STATUS CMS::queue_read_encoded()
{
long queuing_header_offset;
if (!read_permission_flag) {
rcs_print_error("CMS: %s was not configured to read %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
queuing_header_offset = handle_to_global_data->offset;
if (-1 == handle_to_global_data->read(encoded_queuing_header,
encoded_queuing_header_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
decode_queuing_header();
if (queuing_header.queue_length == 0) {
return (status = CMS_READ_OLD);
}
handle_to_global_data->offset += queuing_header.head;
if (-1 == handle_to_global_data->read(encoded_header,
encoded_header_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
rcs_print(" { head=%ld,tail=%ld,end=%ld,length=%ld,id=%ld }\n",
queuing_header.head, queuing_header.tail,
queuing_header.end_queue_space, queuing_header.queue_length,
queuing_header.write_id);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
decode_header();
if (header.in_buffer_size > max_message_size) {
rcs_print_error
("CMS:(%s) Message size of %ld exceeds maximum of %ld\n",
BufferName, header.in_buffer_size, max_message_size);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
header.was_read = 1;
encode_header();
if (-1 ==
handle_to_global_data->write(encoded_header, encoded_header_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
rcs_print(" { head=%ld,tail=%ld,end=%ld,length=%ld,id=%ld }\n",
queuing_header.head,
queuing_header.tail,
queuing_header.end_queue_space,
queuing_header.queue_length, queuing_header.write_id);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data->offset += encoded_header_size;
if (-1 ==
handle_to_global_data->read(encoded_data,
(long) header.in_buffer_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
rcs_print(" { head=%ld,tail=%ld,end=%ld,length=%ld,id=%ld }\n",
queuing_header.head, queuing_header.tail,
queuing_header.end_queue_space, queuing_header.queue_length,
queuing_header.write_id);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
queuing_header.head += header.in_buffer_size + encoded_header_size;
if (queuing_header.head >= queuing_header.end_queue_space) {
queuing_header.head = encoded_queuing_header_size;
}
queuing_header.queue_length--;
if (queuing_header.queue_length == 0) {
queuing_header.head = queuing_header.tail =
encoded_queuing_header_size;
queuing_header.end_queue_space = queuing_header.tail;
}
encode_queuing_header();
handle_to_global_data->offset = queuing_header_offset;
if (-1 == handle_to_global_data->write(encoded_queuing_header,
encoded_queuing_header_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
rcs_print(" { head=%ld,tail=%ld,end=%ld,length=%ld,id=%ld }\n",
queuing_header.head,
queuing_header.tail,
queuing_header.end_queue_space,
queuing_header.queue_length, queuing_header.write_id);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
check_id(header.write_id);
return (status);
}
CMS_STATUS CMS::peek_raw()
{
if (!read_permission_flag) {
rcs_print_error("CMS: %s was not configured to read %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
if (NULL == handle_to_global_data) {
rcs_print_error("CMS:(%s) handle_to_global_data is NULL.\n",
BufferName);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (-1 == handle_to_global_data->read(&header, sizeof(CMS_HEADER))) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (check_id(header.write_id) == CMS_READ_OLD) {
return (status);
}
if (header.in_buffer_size > max_message_size) {
rcs_print_error
("CMS:(%s) Message size of %ld exceeds maximum of %ld\n",
BufferName, header.in_buffer_size, max_message_size);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data->offset += sizeof(CMS_HEADER);
if (-1 ==
handle_to_global_data->read(subdiv_data,
(long) header.in_buffer_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
return (status);
}
CMS_STATUS CMS::queue_peek_raw()
{
if (!read_permission_flag) {
rcs_print_error("CMS: %s was not configured to read %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (-1 == handle_to_global_data->read(&queuing_header,
sizeof(CMS_QUEUING_HEADER))) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (queuing_header.queue_length == 0) {
return (status = CMS_READ_OLD);
}
handle_to_global_data->offset += queuing_header.head;
if (-1 == handle_to_global_data->read(&header, sizeof(CMS_HEADER))) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (header.in_buffer_size > max_message_size) {
rcs_print_error
("CMS:(%s) Message size of %ld exceeds maximum of %ld\n",
BufferName, header.in_buffer_size, max_message_size);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data->offset += sizeof(CMS_HEADER);
if (-1 ==
handle_to_global_data->read(subdiv_data,
(long) header.in_buffer_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
check_id(header.write_id);
return (status);
}
CMS_STATUS CMS::peek_encoded()
{
if (!read_permission_flag) {
rcs_print_error("CMS: %s was not configured to read %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (-1 == handle_to_global_data->read(encoded_header,
encoded_header_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
decode_header();
if (CMS_READ_OLD == check_id(header.write_id)) {
return (CMS_READ_OLD);
}
if (header.in_buffer_size > max_message_size) {
rcs_print_error
("CMS:(%s) Message size of %ld exceeds maximum of %ld\n",
BufferName, header.in_buffer_size, max_message_size);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data->offset += encoded_header_size;
if (-1 == handle_to_global_data->read(encoded_data,
(long) header.in_buffer_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
return (status);
}
CMS_STATUS CMS::queue_peek_encoded()
{
if (!read_permission_flag) {
rcs_print_error("CMS: %s was not configured to read %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (-1 == handle_to_global_data->read(encoded_queuing_header,
encoded_queuing_header_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
decode_queuing_header();
if (queuing_header.queue_length == 0) {
return (status = CMS_READ_OLD);
}
handle_to_global_data->offset += queuing_header.head;
if (-1 == handle_to_global_data->read(encoded_header,
encoded_header_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
decode_header();
if (header.in_buffer_size > max_message_size) {
rcs_print_error
("CMS:(%s) Message size of %ld exceeds maximum of %ld\n",
BufferName, header.in_buffer_size, max_message_size);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data->offset += encoded_header_size;
if (-1 ==
handle_to_global_data->read(encoded_data,
(long) header.in_buffer_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
check_id(header.write_id);
return (status);
}
CMS_STATUS CMS::write_raw(void *user_data, int *serial_number)
{
long current_header_in_buffer_size;
if (!write_permission_flag) {
rcs_print_error("CMS: %s was not configured to write to %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
current_header_in_buffer_size = header.in_buffer_size;
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
#if 0#endif
if (-1 == handle_to_global_data->read(&header, sizeof(header))) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
header.was_read = 0;
header.write_id++;
if (split_buffer) {
if ((header.write_id & 1) != toggle_bit) {
header.write_id++;
}
}
header.in_buffer_size = current_header_in_buffer_size;
if (-1 == handle_to_global_data->write(&header, sizeof(header))) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (NULL != serial_number) {
*serial_number = (int)header.write_id;
}
if (!disable_final_write_raw_for_dma) {
handle_to_global_data->offset += sizeof(CMS_HEADER);
if (-1 == handle_to_global_data->write(user_data, (long)
current_header_in_buffer_size)) {
rcs_print_error
("CMS:(%s) Error writing %ld bytes to global memory at offset %p\n (See %s line %d.)\n",
BufferName, header.in_buffer_size, user_data, __FILE__,
__LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
}
return (status = CMS_WRITE_OK);
}
CMS_STATUS CMS::queue_write_raw(void *user_data, int *serial_number)
{
CMS_HEADER current_header;
long queuing_header_offset;
long original_tail;
if (!write_permission_flag) {
rcs_print_error("CMS: %s was not configured to write to %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
current_header = header;
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
queuing_header_offset = handle_to_global_data->offset;
if (-1 == handle_to_global_data->read(&queuing_header,
sizeof(CMS_QUEUING_HEADER))) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (handle_to_global_data->size - queuing_header.tail -
queuing_header_offset >
((long) (header.in_buffer_size + sizeof(CMS_HEADER)))
&& queuing_header.tail > queuing_header.head) {
free_space =
handle_to_global_data->size - queuing_header.tail -
queuing_header_offset;
} else if (queuing_header.tail < queuing_header.head) {
free_space = queuing_header.head - queuing_header.tail;
} else if (queuing_header.head >
((long) (queuing_header_offset + sizeof(CMS_QUEUING_HEADER) +
(header.in_buffer_size + sizeof(CMS_HEADER))))) {
queuing_header.end_queue_space = queuing_header.tail;
queuing_header.tail = sizeof(CMS_QUEUING_HEADER);
free_space =
queuing_header.head - sizeof(CMS_QUEUING_HEADER) -
queuing_header_offset;
} else {
free_space = 0;
}
if (queuing_header.queue_length == 0) {
queuing_header.head = queuing_header.tail =
sizeof(CMS_QUEUING_HEADER);
queuing_header.queue_length = 0;
queuing_header.end_queue_space = queuing_header.tail;
free_space = handle_to_global_data->size
- sizeof(CMS_QUEUING_HEADER) - queuing_header_offset;
}
if (cms_print_queue_free_space) {
rcs_print("queue free space = %ld\n", free_space);
rcs_print(" { head=%ld,tail=%ld,end=%ld,length=%ld,id=%ld }\n",
queuing_header.head,
queuing_header.tail,
queuing_header.end_queue_space,
queuing_header.queue_length, queuing_header.write_id);
}
if (free_space < ((long) (header.in_buffer_size + sizeof(CMS_HEADER)))) {
if (cms_print_queue_free_space || cms_print_queue_full_messages) {
rcs_print_error("CMS: %s message queue is full.\n", BufferName);
rcs_print_error
("(continued) CMS: Message requires %ld bytes but only %ld bytes are left.\n",
header.in_buffer_size, free_space);
}
return (status = CMS_QUEUE_FULL);
}
original_tail = queuing_header.tail;
queuing_header.tail += header.in_buffer_size + sizeof(CMS_HEADER);
queuing_header.queue_length++;
queuing_header.write_id++;
if (queuing_header.end_queue_space < queuing_header.tail) {
queuing_header.end_queue_space = queuing_header.tail;
}
if (-1 == handle_to_global_data->write(&queuing_header,
sizeof(CMS_QUEUING_HEADER))) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
header.write_id = queuing_header.write_id;
header.was_read = 0;
header.in_buffer_size = current_header.in_buffer_size;
handle_to_global_data->offset += original_tail;
if (-1 == handle_to_global_data->write(&header, sizeof(header))) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (NULL != serial_number) {
*serial_number = (int)header.write_id;
}
handle_to_global_data->offset += sizeof(CMS_HEADER);
if (-1 == handle_to_global_data->write(user_data,
(long) header.in_buffer_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
return (status = CMS_WRITE_OK);
}
CMS_STATUS CMS::write_encoded()
{
CMS_HEADER current_header;
if (!write_permission_flag) {
rcs_print_error("CMS: %s was not configured to write to %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
current_header = header;
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (header.in_buffer_size > max_message_size) {
rcs_print_error
("CMS:(%s) Message size %ld exceeds maximum for this buffer of %ld.\n",
BufferName, header.in_buffer_size, max_message_size);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (-1 == handle_to_global_data->read(encoded_header,
encoded_header_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
decode_header();
header.was_read = 0;
header.write_id++;
if (split_buffer && (header.write_id % 2) != toggle_bit) {
header.write_id++;
}
header.in_buffer_size = current_header.in_buffer_size;
encode_header();
if (-1 ==
handle_to_global_data->write(encoded_header, encoded_header_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data->offset += encoded_header_size;
if (-1 == handle_to_global_data->write(encoded_data,
(long) header.in_buffer_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
return (status = CMS_WRITE_OK);
}
CMS_STATUS CMS::queue_write_encoded()
{
CMS_HEADER current_header;
long queuing_header_offset;
long original_tail;
if (!write_permission_flag) {
rcs_print_error("CMS: %s was not configured to write to %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
current_header = header;
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
queuing_header_offset = handle_to_global_data->offset;
if (-1 == handle_to_global_data->read(encoded_queuing_header,
encoded_queuing_header_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
decode_queuing_header();
if (handle_to_global_data->size - queuing_header.tail -
queuing_header_offset
>
header.in_buffer_size + encoded_header_size
&& queuing_header.tail > queuing_header.head) {
free_space =
handle_to_global_data->size - queuing_header.tail -
queuing_header_offset;
} else if (queuing_header.tail < queuing_header.head) {
free_space = queuing_header.head - queuing_header.tail;
} else if (queuing_header.head >
encoded_header_size + queuing_header_offset +
header.in_buffer_size + encoded_queuing_header_size) {
queuing_header.end_queue_space = queuing_header.tail;
queuing_header.tail = encoded_queuing_header_size;
free_space =
queuing_header.head - encoded_queuing_header_size -
queuing_header_offset;
} else {
free_space = 0;
}
if (queuing_header.queue_length == 0) {
queuing_header.head = queuing_header.tail =
encoded_queuing_header_size;
queuing_header.queue_length = 0;
queuing_header.end_queue_space = queuing_header.tail;
free_space = handle_to_global_data->size
- encoded_queuing_header_size - queuing_header_offset;
}
if (cms_print_queue_free_space) {
rcs_print("queue free space = %ld\n", free_space);
rcs_print(" { head=%ld,tail=%ld,end=%ld,length=%ld,id=%ld }\n",
queuing_header.head,
queuing_header.tail,
queuing_header.end_queue_space,
queuing_header.queue_length, queuing_header.write_id);
}
if (free_space < header.in_buffer_size + encoded_header_size) {
if (cms_print_queue_free_space || cms_print_queue_full_messages) {
rcs_print_error("CMS: %s message queue is full.\n", BufferName);
rcs_print_error
("(continued) CMS: Message requires %ld bytes but only %ld bytes are left.\n",
header.in_buffer_size, free_space);
}
return (status = CMS_QUEUE_FULL);
}
original_tail = queuing_header.tail;
queuing_header.tail += header.in_buffer_size + encoded_header_size;
queuing_header.queue_length++;
queuing_header.write_id++;
if (queuing_header.end_queue_space < queuing_header.tail) {
queuing_header.end_queue_space = queuing_header.tail;
}
encode_queuing_header();
if (-1 == handle_to_global_data->write(encoded_queuing_header,
encoded_queuing_header_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
header.write_id = queuing_header.write_id;
header.was_read = 0;
header.in_buffer_size = current_header.in_buffer_size;
encode_header();
handle_to_global_data->offset += original_tail;
if (-1 ==
handle_to_global_data->write(encoded_header, encoded_header_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data->offset += encoded_header_size;
if (-1 == handle_to_global_data->write(encoded_data,
(long) header.in_buffer_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
return (status = CMS_WRITE_OK);
}
CMS_STATUS CMS::write_if_read_raw(void *user_data, int *serial_number)
{
CMS_HEADER current_header;
if (!write_permission_flag) {
rcs_print_error("CMS: %s was not configured to write to %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
current_header = header;
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (header.in_buffer_size > max_message_size) {
rcs_print_error
("CMS:(%s) Message size %ld exceeds maximum for this buffer of %ld.\n",
BufferName, header.in_buffer_size, max_message_size);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (-1 == handle_to_global_data->read(&header, sizeof(header))) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (!header.was_read) {
return (status = CMS_WRITE_WAS_BLOCKED);
}
header.was_read = 0;
header.write_id++;
if (split_buffer && (header.write_id % 2) != toggle_bit) {
header.write_id++;
}
header.in_buffer_size = current_header.in_buffer_size;
if (-1 == handle_to_global_data->write(&header, sizeof(header))) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (NULL != serial_number) {
*serial_number = (int)header.write_id;
}
handle_to_global_data->offset += sizeof(CMS_HEADER);
if (-1 == handle_to_global_data->write(user_data,
(long) header.in_buffer_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
return (status = CMS_WRITE_OK);
}
CMS_STATUS CMS::queue_write_if_read_raw(void *user_data, int *serial_number)
{
CMS_HEADER current_header;
long queuing_header_offset;
long original_tail;
if (!write_permission_flag) {
rcs_print_error("CMS: %s was not configured to write to %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
current_header = header;
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
queuing_header_offset = handle_to_global_data->offset;
if (-1 == handle_to_global_data->read(&queuing_header,
sizeof(CMS_QUEUING_HEADER))) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (0 != queuing_header.queue_length) {
return (status = CMS_WRITE_WAS_BLOCKED);
}
if (handle_to_global_data->size - queuing_header.tail -
queuing_header_offset >
((long) (header.in_buffer_size + sizeof(CMS_HEADER)))
&& queuing_header.tail > queuing_header.head) {
free_space =
handle_to_global_data->size - queuing_header.tail -
queuing_header_offset;
} else if (queuing_header.tail < queuing_header.head) {
free_space = queuing_header.head - queuing_header.tail;
} else if (queuing_header.head >
((long) (queuing_header_offset + sizeof(CMS_QUEUING_HEADER) +
header.in_buffer_size + sizeof(CMS_HEADER)))) {
queuing_header.end_queue_space = queuing_header.tail;
queuing_header.tail = sizeof(CMS_QUEUING_HEADER);
free_space =
queuing_header.head - sizeof(CMS_QUEUING_HEADER) -
queuing_header_offset;
} else {
free_space = 0;
}
if (queuing_header.queue_length == 0) {
queuing_header.head = queuing_header.tail =
sizeof(CMS_QUEUING_HEADER);
queuing_header.queue_length = 0;
queuing_header.end_queue_space = queuing_header.tail;
free_space = handle_to_global_data->size
- sizeof(CMS_QUEUING_HEADER) - queuing_header_offset;
}
if (cms_print_queue_free_space) {
rcs_print("queue free space = %ld\n", free_space);
rcs_print(" { head=%ld,tail=%ld,end=%ld,length=%ld,id=%ld }\n",
queuing_header.head,
queuing_header.tail,
queuing_header.end_queue_space,
queuing_header.queue_length, queuing_header.write_id);
}
if (free_space < ((long) (header.in_buffer_size + sizeof(CMS_HEADER)))) {
if (cms_print_queue_free_space || cms_print_queue_full_messages) {
rcs_print_error("CMS: %s message queue is full.\n", BufferName);
rcs_print_error
("(continued) CMS: Message requires %ld bytes but only %ld bytes are left.\n",
header.in_buffer_size, free_space);
}
return (status = CMS_QUEUE_FULL);
}
original_tail = queuing_header.tail;
queuing_header.tail += header.in_buffer_size + sizeof(CMS_HEADER);
queuing_header.queue_length++;
queuing_header.write_id++;
if (queuing_header.end_queue_space < queuing_header.tail) {
queuing_header.end_queue_space = queuing_header.tail;
}
if (-1 == handle_to_global_data->write(&queuing_header,
sizeof(CMS_QUEUING_HEADER))) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
header.write_id = queuing_header.write_id;
header.was_read = 0;
header.in_buffer_size = current_header.in_buffer_size;
handle_to_global_data->offset += original_tail;
if (-1 == handle_to_global_data->write(&header, sizeof(header))) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (NULL != serial_number) {
*serial_number = (int)header.write_id;
}
handle_to_global_data->offset += sizeof(CMS_HEADER);
if (-1 == handle_to_global_data->write(user_data,
(long) header.in_buffer_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
return (status = CMS_WRITE_OK);
}
CMS_STATUS CMS::write_if_read_encoded()
{
CMS_HEADER current_header;
if (!write_permission_flag) {
rcs_print_error("CMS: %s was not configured to write to %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
current_header = header;
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (header.in_buffer_size > max_message_size) {
rcs_print_error
("CMS:(%s) Message size %ld exceeds maximum for this buffer of %ld.\n",
BufferName, header.in_buffer_size, max_message_size);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
if (-1 == handle_to_global_data->read(encoded_header,
encoded_header_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
decode_header();
if (!header.was_read) {
return (status = CMS_WRITE_WAS_BLOCKED);
}
header.was_read = 0;
header.write_id++;
if (split_buffer && (header.write_id % 2) != toggle_bit) {
header.write_id++;
}
header.in_buffer_size = current_header.in_buffer_size;
encode_header();
if (-1 ==
handle_to_global_data->write(encoded_header, encoded_header_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data->offset += encoded_header_size;
if (-1 == handle_to_global_data->write(encoded_data,
(long) header.in_buffer_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
return (status = CMS_WRITE_OK);
}
CMS_STATUS CMS::queue_write_if_read_encoded()
{
CMS_HEADER current_header;
long queuing_header_offset;
long original_tail;
if (!write_permission_flag) {
rcs_print_error("CMS: %s was not configured to write to %s\n",
ProcessName, BufferName);
return (status = CMS_PERMISSIONS_ERROR);
}
current_header = header;
if (NULL == handle_to_global_data) {
rcs_print_error("CMS: handle_to_global_data is NULL.\n");
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
queuing_header_offset = handle_to_global_data->offset;
if (-1 == handle_to_global_data->read(encoded_queuing_header,
encoded_queuing_header_size)) {
rcs_print_error
("CMS:(%s) Error reading from global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
decode_queuing_header();
if (0 != queuing_header.queue_length) {
return (status = CMS_WRITE_WAS_BLOCKED);
}
if (handle_to_global_data->size - queuing_header.tail -
queuing_header_offset > header.in_buffer_size + encoded_header_size
&& queuing_header.tail > queuing_header.head) {
free_space =
handle_to_global_data->size - queuing_header.tail -
queuing_header_offset;
} else if (queuing_header.tail < queuing_header.head) {
free_space = queuing_header.head - queuing_header.tail;
} else if (queuing_header.head >
encoded_header_size + queuing_header_offset +
header.in_buffer_size + encoded_queuing_header_size) {
queuing_header.end_queue_space = queuing_header.tail;
queuing_header.tail = encoded_queuing_header_size;
free_space =
queuing_header.head - encoded_queuing_header_size -
queuing_header_offset;
} else {
free_space = 0;
}
if (queuing_header.queue_length == 0) {
queuing_header.head = queuing_header.tail =
encoded_queuing_header_size;
queuing_header.queue_length = 0;
queuing_header.end_queue_space = queuing_header.tail;
free_space = handle_to_global_data->size
- encoded_queuing_header_size - queuing_header_offset;
}
if (cms_print_queue_free_space) {
rcs_print("queue free space = %ld\n", free_space);
rcs_print(" { head=%ld,tail=%ld,end=%ld,length=%ld,id=%ld }\n",
queuing_header.head,
queuing_header.tail,
queuing_header.end_queue_space,
queuing_header.queue_length, queuing_header.write_id);
}
if (free_space < header.in_buffer_size + encoded_header_size) {
if (cms_print_queue_free_space || cms_print_queue_full_messages) {
rcs_print_error("CMS: %s message queue is full.\n", BufferName);
rcs_print_error
("(continued) CMS: Message requires %ld bytes but only %ld bytes are left.\n",
header.in_buffer_size, free_space);
}
return (status = CMS_QUEUE_FULL);
}
original_tail = queuing_header.tail;
queuing_header.tail += header.in_buffer_size + encoded_header_size;
queuing_header.queue_length++;
queuing_header.write_id++;
if (queuing_header.end_queue_space < queuing_header.tail) {
queuing_header.end_queue_space = queuing_header.tail;
}
encode_queuing_header();
if (-1 == handle_to_global_data->write(encoded_queuing_header,
encoded_queuing_header_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
header.write_id = queuing_header.write_id;
header.was_read = 0;
header.in_buffer_size = current_header.in_buffer_size;
encode_header();
handle_to_global_data->offset += original_tail;
if (-1 ==
handle_to_global_data->write(encoded_header, encoded_header_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
handle_to_global_data->offset += encoded_header_size;
if (-1 == handle_to_global_data->write(encoded_data,
(long) header.in_buffer_size)) {
rcs_print_error("CMS:(%s) Error writing to global memory at %s:%d\n",
BufferName, __FILE__, __LINE__);
return (status = CMS_INTERNAL_ACCESS_ERROR);
}
return (status = CMS_WRITE_OK);
}