blob: ad62076622c6c9057876d6a89994d9ee68f26bba [file] [log] [blame]
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. SPDX-License-Identifier: CC-BY-4.0
.. CAUTION: this document is generated from source in doc/src/rtd.
.. To make changes edit the source and recompile the document.
.. Do NOT make changes directly to .rst or .md files.
RMR User's Guide
============================================================================================
The RIC Message Router (RMR) is a library which applications
use to send and receive messages where the message routing,
endpoint selection, is based on the message type rather than
on traditional DNS names or IP addresses. Because the user
documentation for RMR is a collection of UNIX manpages
(included in the development package, and available via the
man command when installed), there is no separate "User's
Guide." To provide something for the document scrapers to
find, this is a collection of the RMR manual pages formatted
directly from their source which might be a bit ragged when
combined into a single markup document. Read the manual pages
:)
NAME
--------------------------------------------------------------------------------------------
rmr_alloc_msg
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
rmr_mbuf_t* rmr_alloc_msg( void* ctx, int size );
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_alloc_msg function is used to allocate a buffer which
the user programme can write into and then send through the
RMR library. The buffer is allocated such that sending it
requires no additional copying out of the buffer. If the
value passed in size is 0, then the default size supplied on
the *rmr_init* call will be used. The *ctx* parameter is the
void context pointer that was returned by the *rmr_init*
function.
The pointer to the message buffer returned is a structure
which has some user application visible fields; the structure
is described in rmr.h, and is illustrated below.
::
typedef struct {
int state;
int mtype;
int len;
unsigned char* payload;
unsigned char* xaction;
uint sub_id;
uint tp_state;
} rmr_mbuf_t;
state
Is the current buffer state. Following a call to
rmr_send_msg the state indicates whether the buffer was
successfully sent which determines exactly what the
payload points to. If the send failed, the payload
referenced by the buffer is the message that failed to
send (allowing the application to attempt a
retransmission). When the state is RMR_OK the buffer
represents an empty buffer that the application may fill
in in preparation to send.
mtype
When sending a message, the application is expected to set
this field to the appropriate message type value (as
determined by the user programme). Upon send this value
determines how the RMR library will route the message. For
a buffer which has been received, this field will contain
the message type that was set by the sending application.
len
The application using a buffer to send a message is
expected to set the length value to the actual number of
bytes that it placed into the message. This is likely less
than the total number of bytes that the message can carry.
For a message buffer that is passed to the application as
the result of a receive call, this will be the value that
the sending application supplied and should indicate the
number of bytes in the payload which are valid.
payload
The payload is a pointer to the actual received data. The
user programme may read and write from/to the memory
referenced by the payload up until the point in time that
the buffer is used on a rmr_send, rmr_call or rmr_reply
function call. Once the buffer has been passed back to a
RMR library function the user programme should **NOT**
make use of the payload pointer.
xaction
The *xaction* field is a pointer to a fixed sized area in
the message into which the user may write a transaction
ID. The ID is optional with the exception of when the user
application uses the rmr_call function to send a message
and wait for the reply; the underlying RMR processing
expects that the matching reply message will also contain
the same data in the *xaction* field.
sub_id
This value is the subscription ID. It, in combination with
the message type is used by rmr to determine the target
endpoint when sending a message. If the application to
application protocol does not warrant the use of a
subscription ID, the RMR constant RMR_VOID_SUBID should be
placed in this field. When an application is forwarding or
returning a buffer to the sender, it is the application's
responsibility to set/reset this value.
tp_state
For C applications making use of RMR, the state of a
transport based failure will often be available via errno.
However, some wrapper environments may not have direct access
to the C-lib errno value. RMR send and receive operations
will place the current value of errno into this field which
should make it available to wrapper functions. User
applications are strongly cautioned against relying on the
value of errno as some transport mechanisms may not set this
value on all calls. This value should also be ignored any
time the message status is RMR_OK.
RETURN VALUE
--------------------------------------------------------------------------------------------
The function returns a pointer to a rmr_mbuf structure, or NULL
on error.
ERRORS
--------------------------------------------------------------------------------------------
ENOMEM
Unable to allocate memory.
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_tralloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
rmr_init_trace(3), rmr_get_trace(3), rmr_get_trlen(3),
rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3), rmr_fib(3),
rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3),
rmr_ring_free(3), rmr_set_trace(3)
NAME
--------------------------------------------------------------------------------------------
rmr_bytes2meid
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
int rmr_bytes2meid( rmr_mbuf_t* mbuf, unsigned char* src, int len )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_bytes2meid function will copy up to *len* butes from
*src* to the managed entity ID (meid) field in the message.
The field is a fixed length, gated by the constant
RMR_MAX_MEID and if len is larger than this value, only
RMR_MAX_MEID bytes will actually be copied.
RETURN VALUE
--------------------------------------------------------------------------------------------
On success, the actual number of bytes copied is returned, or
-1 to indicate a hard error. If the length is less than 0, or
not the same as length passed in, errno is set to one of the
errors described in the *Errors* section.
ERRORS
--------------------------------------------------------------------------------------------
If the returned length does not match the length passed in,
errno will be set to one of the following constants with the
meaning listed below.
EINVAL
The message, or an internal portion of the message, was
corrupted or the pointer was invalid.
EOVERFLOW
The length passed in was larger than the maximum length of
the field; only a portion of the source bytes were copied.
EXAMPLE
--------------------------------------------------------------------------------------------
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_call(3),
rmr_free_msg(3), rmr_get_rcvfd(3), rmr_get_meid(3),
rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3),
rmr_ring_free(3), rmr_str2meid(3), rmr_str2xact(3),
rmr_wh_open(3), rmr_wh_send_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_bytes2payload
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
void rmr_bytes2payload( rmr_mbuf_t* mbuf, unsigned char* src, int len )
DESCRIPTION
--------------------------------------------------------------------------------------------
This is a convenience function as some wrapper languages
might not have the ability to directly copy into the payload
buffer. The bytes from *src* for the length given are copied
to the payload. It is the caller's responsibility to ensure
that the payload is large enough. Upon successfully copy, the
len field in the message buffer is updated to reflect the
number of bytes copied.
There is little error checking, and no error reporting.
RETURN VALUE
--------------------------------------------------------------------------------------------
None.
EXAMPLE
--------------------------------------------------------------------------------------------
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_bytes2payload(3),
rmr_call(3), rmr_free_msg(3), rmr_get_rcvfd(3),
rmr_get_meid(3), rmr_payload_size(3), rmr_send_msg(3),
rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_bytes2xact
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
int rmr_bytes2xact( rmr_mbuf_t* mbuf, unsigned char* src, int len )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_bytes2xact function will copy up to *len* butes from
*src* to the transaction ID (xaction) field in the message.
The field is a fixed length, gated by the constant
RMR_MAX_XID and if len is larger than this value, only
RMR_MAX_XID bytes will actually be copied.
RETURN VALUE
--------------------------------------------------------------------------------------------
On success, the actual number of bytes copied is returned,
or -1 to indicate a hard error. If the length is less than
0, or not the same as length passed in, errno is set to
one of the errors described in the *Errors* section.
ERRORS
--------------------------------------------------------------------------------------------
If the returned length does not match the length passed
in, errno will be set to one of the following constants
with the meaning listed below.
EINVAL
The message, or an internal portion of the message, was
corrupted or the pointer was invalid.
EOVERFLOW
The length passed in was larger than the maximum length of
the field; only a portion of the source bytes were copied.
EXAMPLE
--------------------------------------------------------------------------------------------
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_bytes2meid(3), rmr_call(3),
rmr_free_msg(3), rmr_get_meid(3), rmr_get_rcvfd(3),
rmr_get_xact(3), rmr_payload_size(3), rmr_send_msg(3),
rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
rmr_wh_open(3), rmr_wh_send_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_call
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
extern rmr_mbuf_t* rmr_call( void* vctx, rmr_mbuf_t* msg );
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_call function sends the user application message to a
remote endpoint, and waits for a corresponding response
message before returning control to the user application. The
user application supplies a completed message buffer, as it
would for a rmr_send call, but unlike with the send, the
buffer returned will have the response from the application
that received the message.
Messages which are received while waiting for the response
are queued internally by RMR, and are returned to the user
application when rmr_rcv_msg is invoked. These messages are
returned in th order received, one per call to rmr_rcv_msg.
Call Timeout
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The rmr_call function implements a timeout failsafe to
prevent, in most cases, the function from blocking forever.
The timeout period is **not** based on time (calls to clock
are deemed too expensive for a low latency system level
library, but instead the period is based on the number of
received messages which are not the response. Using a
non-time mechanism for *timeout* prevents the async queue
from filling (which would lead to message drops) in an
environment where there is heavy message traffic.
When the threshold number of messages have been queued
without receiving a response message, control is returned to
the user application and a NULL pointer is returned to
indicate that no message was received to process. Currently
the threshold is fixed at 20 messages, though in future
versions of the library this might be extended to be a
parameter which the user application may set.
Retries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The send operations in RMr will retry *soft* send failures
until one of three conditions occurs:
1.
The message is sent without error
2.
The underlying transport reports a * hard * failure
3.
The maximum number of retry loops has been attempted
A retry loop consists of approximately 1000 send attemps **
without** any intervening calls to * sleep() * or * usleep().
* The number of retry loops defaults to 1, thus a maximum of
1000 send attempts is performed before returning to the user
application. This value can be set at any point after RMr
initialisation using the * rmr_set_stimeout() * function
allowing the user application to completely disable retires
(set to 0), or to increase the number of retry loops.
Transport Level Blocking
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The underlying transport mechanism used to send messages is
configured in *non-blocking* mode. This means that if a
message cannot be sent immediately the transport mechanism
will **not** pause with the assumption that the inability to
send will clear quickly (within a few milliseconds). This
means that when the retry loop is completely disabled (set to
0), that the failure to accept a message for sending by the
underlying mechanisms (software or hardware) will be reported
immediately to the user application.
It should be noted that depending on the underlying transport
mechanism being used, it is extremly possible that during
normal operations that retry conditions are very likely to
happen. These are completely out of RMr's control, and there
is nothing that RMr can do to avoid or midigate these other
than by allowing RMr to retry the send operation, and even
then it is possible (e.g. during connection reattempts), that
a single retry loop is not enough to guarentee a successful
send.
RETURN VALUE
--------------------------------------------------------------------------------------------
The rmr_call function returns a pointer to a message buffer
with the state set to reflect the overall state of call
processing (see Errors below). In some cases a NULL pointer
will be returned; when this is the case only *errno* will be
available to describe the reason for failure.
ERRORS
--------------------------------------------------------------------------------------------
These values are reflected in the state field of the returned
message.
RMR_OK
The call was successful and the message buffer references
the response message.
RMR_ERR_CALLFAILED
The call failed and the value of *errno,* as described
below, should be checked for the specific reason.
The global "variable" *errno* will be set to one of the
following values if the overall call processing was not
successful.
ETIMEDOUT
Too many messages were queued before receiving the
expected response
ENOBUFS
The queued message ring is full, messages were dropped
EINVAL
A parameter was not valid
EAGAIN
The underlying message system wsa interrupted or the
device was busy; the message was **not** sent, and user
application should call this function with the message
again.
EXAMPLE
--------------------------------------------------------------------------------------------
The following code bit shows one way of using the rmr_call
function, and illustrates how the transaction ID must be set.
::
int retries_left = 5; // max retries on dev not available
int retry_delay = 50000; // retry delay (usec)
static rmr_mbuf_t* mbuf = NULL; // response msg
msg_t* pm; // private message (payload)
m// get a send buffer and reference the payload
mbuf = rmr_alloc_msg( mr, RMR_MAX_RCV_BYTES );
pm = (msg_t*) mbuf->payload;
p// generate an xaction ID and fill in payload with data and msg type
snprintf( mbuf->xaction, RMR_MAX_XID, "%s", gen_xaction() );
snprintf( pm->req, sizeof( pm->req ), "{ \\"req\\": \\"num users\\"}" );
mbuf->mtype = MT_REQ;
msg = rmr_call( mr, msg );
if( ! msg ) { // probably a timeout and no msg received
return NULL; // let errno trickle up
}
if( mbuf->state != RMR_OK ) {
while( retries_left-- > 0 && // loop as long as eagain
errno == EAGAIN &&
(msg = rmr_call( mr, msg )) != NULL &&
mbuf->state != RMR_OK ) {
usleep( retry_delay );
}
if( mbuf == NULL || mbuf->state != RMR_OK ) {
rmr_free_msg( mbuf ); // safe if nil
return NULL;
}
}
// do something with mbuf
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_free_msg(3), rmr_init(3),
rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
rmr_fib(3), rmr_has_str(3), rmr_set_stimeout(3),
rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3)
NAME
--------------------------------------------------------------------------------------------
rmr_wh_open
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
void rmr_close( void* vctx )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_close function closes the listen socket effectively
cutting the application off. The route table listener is also
stopped. Calls to rmr_rcv_msg() will fail with unpredictable
error codes, and calls to rmr_send_msg(), rmr_call(), and
rmr_rts_msg() will have unknown results.
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
rmr_get_rcvfd(3), rmr_payload_size(3), rmr_send_msg(3),
rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
rmr_mk_ring(3), rmr_ring_free(3), rmr_wh_open(3),
rmr_wh_send_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_free_msg
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
void rmr_free_msg( rmr_mbuf_t* mbuf );
DESCRIPTION
--------------------------------------------------------------------------------------------
The message buffer is returned to the pool, or the associated
memory is released depending on the needs of the underlying
messaging system. This allows the user application to release
a buffer that is not going to be used. It is safe to pass a
nil pointer to this function, and doing so does not result in
a change to the value of errrno.
After calling, the user application should **not** use any of
the pointers (transaction ID, or payload) which were
available.
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_init(3),
rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3),
rmr_ring_free(3)
NAME
--------------------------------------------------------------------------------------------
rmr_get_meid
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
char* rmr_get_meid( rmr_mbuf_t* mbuf, unsigned char* dest )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_get_meid function will copy the managed entity ID
(meid) field from the message into the *dest* buffer provided
by the user. The buffer referenced by *dest* is assumed to be
at least RMR_MAX_MEID bytes in length. If *dest* is NULL,
then a buffer is allocated (the calling application is
expected to free when the buffer is no longer needed).
RETURN VALUE
--------------------------------------------------------------------------------------------
On success, a pointer to the extracted string is returned. If
*dest* was supplied, then this is just a pointer to the
caller's buffer. If *dest* was NULL, this is a pointer to the
allocated buffer. If an error occurs, a nil pointer is
returned and errno is set as described below.
ERRORS
--------------------------------------------------------------------------------------------
If an error occurs, the value of the global variable errno
will be set to one of the following with the indicated
meaning.
EINVAL
The message, or an internal portion of the message, was
corrupted or the pointer was invalid.
ENOMEM
A nil pointer was passed for *dest,* however it was not
possible to allocate a buffer using malloc().
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_bytes2meid(3),
rmr_call(3), rmr_free_msg(3), rmr_get_rcvfd(3),
rmr_get_xact(3), rmr_payload_size(3), rmr_send_msg(3),
rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_get_rcvfd
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
void* rmr_get_rcvfd( void* ctx )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_get_rcvfd function returns a file descriptor which
may be given to epoll_wait() by an application that wishes to
use event poll in a single thread rather than block on the
arrival of a message via calls to rmr_rcv_msg(). When
epoll_wait() indicates that this file descriptor is ready, a
call to rmr_rcv_msg() will not block as at least one message
has been received.
The context (ctx) pointer passed in is the pointer returned
by the call to rmr_init().
**NOTE:** There is no support for epoll in Nanomsg, thus his
function is only supported when linking with the NNG version
of RMr and the file descriptor returned when using the
Nanomsg verfsion will always return an error.
RETURN VALUE
--------------------------------------------------------------------------------------------
The rmr_get_rcvfd function returns a file descriptor greater
or equal to 0 on success and -1 on error. If this function is
called from a user application linked against the Nanomsg RMr
library, calls will always return -1 with errno set to
EINVAL.
ERRORS
--------------------------------------------------------------------------------------------
The following error values are specifically set by this RMR
function. In some cases the error message of a system call is
propagated up, and thus this list might be incomplete.
EINVAL
The use of this function is invalid in this environment.
EXAMPLE
--------------------------------------------------------------------------------------------
The following short code bit illustrates the use of this
function. Error checking has been omitted for clarity.
::
#include <stdio.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <rmr/rmr.h>
int main() {
int rcv_fd; // pollable fd
void* mrc; //msg router context
struct epoll_event events[10]; // support 10 events to poll
struct epoll_event epe; // event definition for event to listen to
int ep_fd = -1;
rmr_mbuf_t* msg = NULL;
int nready;
int i;
mrc = rmr_init( "43086", RMR_MAX_RCV_BYTES, RMRFL_NONE );
rcv_fd = rmr_get_rcvfd( mrc );
rep_fd = epoll_create1( 0 ); _ B ,// initialise epoll environment
epe.events = EPOLLIN;
epe.data.fd = rcv_fd;
epoll_ctl( ep_fd, EPOLL_CTL_ADD, rcv_fd, &epe ); // add our info to the mix
while( 1 ) {
nready = epoll_wait( ep_fd, events, 10, -1 ); // -1 == block forever (no timeout)
for( i = 0; i < nready && i < 10; i++ ) { // loop through to find what is ready
if( events[i].data.fd == rcv_fd ) { // RMr has something
msg = rmr_rcv_msg( mrc, msg );
if( msg ) {
// do something with msg
}
}
// check for other ready fds....
}
}
}
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3),
rmr_ring_free(3)
NAME
--------------------------------------------------------------------------------------------
rmr_get_src
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
unsigned char* rmr_get_src( rmr_mbuf_t* mbuf, unsigned char* dest )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_get_src function will copy the *source* information
from the message to a buffer (dest) supplied by the user. In
an RMr message, the source is the sender's information that
is used for return to sender function calls, and is generally
the hostname and port in the form *name*. The source might be
an IP address port combination; the data is populated by the
sending process and the only requirement is that it be
capable of being used to start a TCP session with the sender.
The maximum size allowed by RMr is 64 bytes (including the
nil string terminator), so the user must ensure that the
destination buffer given is at least 64 bytes.
RETURN VALUE
--------------------------------------------------------------------------------------------
On success, a pointer to the destination buffer is given as a
convenience to the user programme. On failure, a nil pointer
is returned and the value of errno is set.
ERRORS
--------------------------------------------------------------------------------------------
If an error occurs, the value of the global variable errno
will be set to one of the following with the indicated
meaning.
EINVAL
The message, or an internal portion of the message, was
corrupted or the pointer was invalid.
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_bytes2meid(3),
rmr_call(3), rmr_free_msg(3), rmr_get_rcvfd(3),
rmr_get_srcip(3), rmr_payload_size(3), rmr_send_msg(3),
rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_get_srcip
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
unsigned char* rmr_get_srcip( rmr_mbuf_t* mbuf, unsigned char* dest )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_get_srcip function will copy the *source IP address*
from the message to a buffer (dest) supplied by the user. In
an RMr message, the source IP address is the sender's
information that is used for return to sender function calls;
this function makes it available to the user application. The
address is maintained as IP:port where *IP* could be either
an IPv6 or IPv4 address depending on what was provided by the
sending application.
The maximum size allowed by RMr is 64 bytes (including the
nil string terminator), so the user must ensure that the
destination buffer given is at least 64 bytes. The user
application should use the RMr constant RMR_MAX_SRC to ensure
that the buffer supplied is large enough, and to protect
against future RMr enhancements which might increase the
address buffer size requirement.
RETURN VALUE
--------------------------------------------------------------------------------------------
On success, a pointer to the destination buffer is given as a
convenience to the user programme. On failure, a nil pointer
is returned and the value of errno is set.
ERRORS
--------------------------------------------------------------------------------------------
If an error occurs, the value of the global variable errno
will be set to one of the following with the indicated
meaning.
EINVAL
The message, or an internal portion of the message, was
corrupted or the pointer was invalid.
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_bytes2meid(3),
rmr_call(3), rmr_free_msg(3), rmr_get_rcvfd(3),
rmr_get_src(3), rmr_payload_size(3), rmr_send_msg(3),
rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_get_trace
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
int rmr_get_trace( rmr_mbuf_t* mbuf, unsigned char* dest, int size )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_get_trace function will copy the trace information
from the message into the user's allocated memory referenced
by dest. The size parameter is assumed to be the maximum
number of bytes which can be copied (size of the destination
buffer).
RETURN VALUE
--------------------------------------------------------------------------------------------
On success, the number of bytes actually copied is returned.
If the return value is 0, no bytes copied, then the reason
could be that the message pointer was nil, or the size
parameter was <= 0.
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_tralloc_msg(3), rmr_bytes2xact(3),
rmr_bytes2meid(3), rmr_call(3), rmr_free_msg(3),
rmr_get_rcvfd(3), rmr_get_trlen(3), rmr_init(3),
rmr_init_trace(3), rmr_payload_size(3), rmr_send_msg(3),
rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3),
rmr_set_trace(3), rmr_trace_ref(3)
NAME
--------------------------------------------------------------------------------------------
rmr_get_trlen
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
int rmr_get_trlen( rmr_mbuf_t* msg );
DESCRIPTION
--------------------------------------------------------------------------------------------
Given a message buffer, this function returns the amount of
space (bytes) that have been allocated for trace data. If no
trace data has been allocated, then 0 is returned.
RETURN VALUE
--------------------------------------------------------------------------------------------
The number of bytes allocated for trace information in the
given message.
ERRORS
--------------------------------------------------------------------------------------------
INVAL
Parameter(s) passed to the function were not valid.
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
rmr_get_trace(3), rmr_init(3), rmr_init_trace(3),
rmr_send_msg(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3),
rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3),
rmr_set_trace(3), rmr_tralloc_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_get_xact
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
char* rmr_get_xact( rmr_mbuf_t* mbuf, unsigned char* dest )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_get_xact function will copy the transaction field
from the message into the *dest* buffer provided by the user.
The buffer referenced by *dest* is assumed to be at least
RMR_MAX_XID bytes in length. If *dest* is NULL, then a buffer
is allocated (the calling application is expected to free
when the buffer is no longer needed).
RETURN VALUE
--------------------------------------------------------------------------------------------
On success, a pointer to the extracted string is returned. If
*dest* was supplied, then this is just a pointer to the
caller's buffer. If *dest* was NULL, this is a pointer to the
allocated buffer. If an error occurs, a nil pointer is
returned and errno is set as described below.
ERRORS
--------------------------------------------------------------------------------------------
If an error occurs, the value of the global variable errno
will be set to one of the following with the indicated
meaning.
EINVAL
The message, or an internal portion of the message, was
corrupted or the pointer was invalid.
ENOMEM
A nil pointer was passed for *dest,* however it was not
possible to allocate a buffer using malloc().
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_bytes2meid(3),
rmr_call(3), rmr_free_msg(3), rmr_get_rcvfd(3),
rmr_get_meid(3), rmr_payload_size(3), rmr_send_msg(3),
rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_init
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
void* rmr_init( char* proto_port, int max_msg_size, int flags );
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_init function prepares the environment for sending
and receiving messages. It does so by establishing a worker
thread (pthread) which subscribes to a route table generator
which provides the necessary routing information for the RMR
library to send messages.
*Port* is used to listen for connection requests from other
RMR based applications. The value of *max_msg_size* will be
used when allocating zero copy send buffers which must be
allocated, possibly, prior to the application knowing the
actual size of a specific message.
*Flags* allows for selection of some RMr options at the time
of initialisation. These are set by ORing RMRFL constants
from the RMr header file. Currently the following flags are
supported:
RMRFL_NONE
No flags are set.
RMRFL_NOTHREAD
The route table collector thread is not to be started.
This should only be used by the route table generator
application if it is based on RMr.
RMRFL_MTCALL
Enable multi-threaded call support.
Multi-threaded Calling
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The support for an application to issue a *blocking call* by
the rmr_call() function was limited such that only user
applications which were operating in a single thread could
safely use the function. Further, timeouts were message count
based and not time unit based. Multi-threaded call support
adds the ability for a user application with multiple threads
to invoke a blocking call function with the guarentee that
the correct response message is delivered to the thread. The
additional support is implemented with the *rmr_mt_call()*
and *rmr_mt_rcv()* function calls.
Multi-threaded call support requires the user application to
specifically enable it when RMr is initialised. This is
necessary because a second, dedicated, receiver thread must
be started, and requires all messages to be examined and
queued by this thread. The additional overhead is minimal,
queuing information is all in the RMr message header, but as
an additional process is necessary the user application must
"opt in" to this approach.
ENVIRONMENT
--------------------------------------------------------------------------------------------
As a part of the initialisation process rmr_init will look
into the available environment variables to influence it's
setup. The following variables will be used when found.
RMR_SEED_RT
Assumes this is the filename of the seed route table file
to use. In normal situations, the library will wait for an
update from the route table generator (expected within a
few seconds of initialisation) before being able to send
messages. However, in some situations where a bootstrap
table is necessary, this is the means to supply it to the
library.
RMR_RTG_SVC
The route table generator assumes that RMr is listening on
a well known port (4561) by default, but this environment
variable can be used to change the listening port if
needed. The value of the variable is expected to be just
the port.
RETURN VALUE
--------------------------------------------------------------------------------------------
The rmr_init function returns a void pointer (a contex if you
will) that is passed as the first parameter to nearly all
other RMR functions. If rmr_init is unable to properly
initialise the environment, NULL is returned and errno is set
to an appropriate value.
ERRORS
--------------------------------------------------------------------------------------------
The following error values are specifically set by this RMR
function. In some cases the error message of a system call is
propagated up, and thus this list might be incomplete.
ENOMEM
Unable to allocate memory.
EXAMPLE
--------------------------------------------------------------------------------------------
::
void* uh;
rmr_mbuf* buf = NULL;
uh = rmr_init( "43086", 4096, 0 );
buf = rmr_rcv_msg( uh, buf );
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
rmr_get_rcvfd(3), rmr_mt_call(3), rmr_mt_rcv(3),
rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3),
rmr_ring_free(3)
NAME
--------------------------------------------------------------------------------------------
rmr_init_trace
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
void* rmr_init_trace( void* ctx )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_init_trace function establishes the default trace
space placed in each message buffer allocated with
rmr_alloc_msg(). If this function is never called, then no
trace space is allocated by default into any message buffer.
Trace space allows the user application to pass some trace
token, or other data with the message, but outside of the
payload. Trace data may be added to any message with
rmr_set_trace(), and may be extracted from a message with
rmr_get_trace(). The number of bytes that a message contains
for/with trace data can be determined by invoking
rmr_get_trlen().
This function may be safely called at any time during the
life of the user programme to (re)set the default trace space
reserved. If the user programme needs to allocate a message
with trace space of a different size than is allocated by
default, without fear of extra overhead of reallocating a
message later, the rmr_tralloc_msg() function can be used.
RETURN VALUE
--------------------------------------------------------------------------------------------
A value of 1 is returned on success, and 0 on failure. A
failure indicates that the RMr context (a void pointer passed
to this function was not valid.
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_tr_alloc_msg(3), rmr_call(3),
rmr_free_msg(3), rmr_get_rcvfd(3), rmr_get_trace(3),
rmr_get_trlen(3), rmr_payload_size(3), rmr_send_msg(3),
rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
rmr_mk_ring(3), rmr_ring_free(3), rmr_set_trace(3)
NAME
--------------------------------------------------------------------------------------------
rmr_mt_call
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
extern rmr_mbuf_t* rmr_mt_call( void* vctx, rmr_mbuf_t* msg, int id, int timeout );
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_mt_call function sends the user application message
to a remote endpoint, and waits for a corresponding response
message before returning control to the user application. The
user application supplies a completed message buffer, as it
would for a rmr_send_msg call, but unlike with a send, the
buffer returned will have the response from the application
that received the message. The thread invoking the
*rmr_mt_call()* will block until a message arrives or until
*timeout* milliseconds has passed; which ever comes first.
Using a timeout value of zero (0) will cause the thread to
block without a timeout.
The *id* supplied as the third parameter is an integer in the
range of 2 through 255 inclusive. This is a caller defined
"thread number" and is used to match the response message
with the correct user application thread. If the ID value is
not in the proper range, the attempt to make the call will
fail.
Messages which are received while waiting for the response
are queued on a *normal* receive queue and will be delivered
to the user application with the next invocation of
*rmr_mt_rcv()* or *rmr_rvv_msg().* by RMR, and are returned
to the user application when rmr_rcv_msg is invoked. These
messages are returned in th order received, one per call to
rmr_rcv_msg.
NOTE: Currently the multi-threaded functions are supported
only when the NNG transport mechanism is being used. It will
not be possible to link a programme using the Nanomsg version
of the library when references to this function are present.
The Transaction ID
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The user application is responsible for setting the value of
the transaction ID field before invoking *rmr_mt_call.* The
transaction ID is a RMR_MAX_XID byte field that is used to
match the response message when it arrives. RMr will compare
**all** of the bytes in the field, so the caller must ensure
that they are set correctly to avoid missing the response
message. (The application which returns the response message
is also expected to ensure that the return buffer has the
matching transaction ID. This can be done transparently if
the application uses the *rmr_rts_msg()* function and does
not adjust the transaction ID.
Retries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The send operations in RMr will retry *soft* send failures
until one of three conditions occurs:
1.
The message is sent without error
2.
The underlying transport reports a * hard * failure
3.
The maximum number of retry loops has been attempted
A retry loop consists of approximately 1000 send attemps **
without** any intervening calls to * sleep() * or * usleep().
* The number of retry loops defaults to 1, thus a maximum of
1000 send attempts is performed before returning to the user
application. This value can be set at any point after RMr
initialisation using the * rmr_set_stimeout() * function
allowing the user application to completely disable retires
(set to 0), or to increase the number of retry loops.
Transport Level Blocking
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The underlying transport mechanism used to send messages is
configured in *non-blocking* mode. This means that if a
message cannot be sent immediately the transport mechanism
will **not** pause with the assumption that the inability to
send will clear quickly (within a few milliseconds). This
means that when the retry loop is completely disabled (set to
0), that the failure to accept a message for sending by the
underlying mechanisms (software or hardware) will be reported
immediately to the user application.
It should be noted that depending on the underlying transport
mechanism being used, it is extremly possible that during
normal operations that retry conditions are very likely to
happen. These are completely out of RMr's control, and there
is nothing that RMr can do to avoid or midigate these other
than by allowing RMr to retry the send operation, and even
then it is possible (e.g. during connection reattempts), that
a single retry loop is not enough to guarentee a successful
send.
RETURN VALUE
--------------------------------------------------------------------------------------------
The rmr_mt_call function returns a pointer to a message
buffer with the state set to reflect the overall state of
call processing. If the state is RMR_OK then the buffer
contains the response message; otherwise the state indicates
the error encountered while attempting to send the message.
If no response message is received when the timeout period
has expired, a nil pointer will be returned (NULL).
ERRORS
--------------------------------------------------------------------------------------------
These values are reflected in the state field of the returned
message.
RMR_OK
The call was successful and the message buffer references
the response message.
RMR_ERR_BADARG
An argument passed to the function was invalid.
RMR_ERR_CALLFAILED
The call failed and the value of *errno,* as described
below, should be checked for the specific reason.
RMR_ERR_NOENDPT
An endpoint associated with the message type could not be
found in the route table.
RMR_ERR_RETRY
The underlying transport mechanism was unable to accept
the message for sending. The user application can retry
the call operation if appropriate to do so.
The global "variable" *errno* will be set to one of the
following values if the overall call processing was not
successful.
ETIMEDOUT
Too many messages were queued before receiving the
expected response
ENOBUFS
The queued message ring is full, messages were dropped
EINVAL
A parameter was not valid
EAGAIN
The underlying message system wsa interrupted or the
device was busy; the message was **not** sent, and user
application should call this function with the message
again.
EXAMPLE
--------------------------------------------------------------------------------------------
The following code bit shows one way of using the rmr_mt_call
function, and illustrates how the transaction ID must be set.
::
int retries_left = 5; // max retries on dev not available
static rmr_mbuf_t* mbuf = NULL; // response msg
msg_t* pm; // private message (payload)
m// get a send buffer and reference the payload
mbuf = rmr_alloc_msg( mr, RMR_MAX_RCV_BYTES );
pm = (msg_t*) mbuf->payload;
p// generate an xaction ID and fill in payload with data and msg type
rmr_bytes2xact( mbuf, xid, RMR_MAX_XID );
snprintf( pm->req, sizeof( pm->req ), "{ \\"req\\": \\"num users\\"}" );
mbuf->mtype = MT_USR_RESP;
msg = rmr_mt_call( mr, msg, my_id, 100 ); e :// wait up to 100ms
if( ! msg ) { // probably a timeout and no msg received
return NULL; // let errno trickle up
}
if( mbuf->state != RMR_OK ) {
while( retries_left-- > 0 && // loop as long as eagain
mbuf->state == RMR_ERR_RETRY &&
(msg = rmr_mt_call( mr, msg )) != NULL &&
mbuf->state != RMR_OK ) {
usleep( retry_delay );
}
if( mbuf == NULL || mbuf->state != RMR_OK ) {
rmr_free_msg( mbuf ); // safe if nil
return NULL;
}
}
// do something with mbuf
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_free_msg(3), rmr_init(3),
rmr_mt_rcv(3), rmr_payload_size(3), rmr_send_msg(3),
rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
rmr_ready(3), rmr_fib(3), rmr_has_str(3),
rmr_set_stimeout(3), rmr_tokenise(3), rmr_mk_ring(3),
rmr_ring_free(3)
NAME
--------------------------------------------------------------------------------------------
rmr_mt_rcv
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
rmr_mbuf_t* rmr_mt_rcv( void* vctx, rmr_mbuf_t* old_msg, int timeout );
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_mt_rcv function blocks until a message is received,
or the timeout period (milliseconds) has passed. The result
is an RMr message buffer which references a received message.
In the case of a timeout the state will be reflected in an
"empty buffer" (if old_msg was not nil, or simply with the
return of a nil pointer. If a timeout value of zero (0) is
given, then the function will block until the next message
received.
The *vctx* pointer is the pointer returned by the rmr_init
function. *Old_msg* is a pointer to a previously used message
buffer or NULL. The ability to reuse message buffers helps to
avoid alloc/free cycles in the user application. When no
buffer is available to supply, the receive function will
allocate one.
The *old_msg* parameter allows the user to pass a previously
generated RMr message back to RMr for reuse. Optionally, the
user application may pass a nil pointer if no reusable
message is available. When a timeout occurs, and old_msg was
not nil, the state will be returned by returning a pointer to
the old message with the state set.
It is possible to use the *rmr_rcv_msg()* function instead of
this function. Doing so might be advantagous if the user
programme does not always start the multi-threaded mode and
the use of *rmr_rcv_msg()* would make the flow of the code
more simple. The advantags of using this function are the
ability to set a timeout without using epoll, and a small
performance gain (if multi-threaded mode is enabled, and the
*rmr_rcv_msg()* function is used, it simply invokes this
function without a timeout value, thus there is the small
cost of a second call that results). Similarly, the
*rmr_torcv_msg()* call can be used when in multi-threaded
mode with the same "pass through" overhead to using this
function directly.
NOTE: Currently the multi-threaded functions are supported
only when the NNG transport mechanism is being used. It will
not be possible to link a programme using the nanomsg version
of the library when references to this function are present.
RETURN VALUE
--------------------------------------------------------------------------------------------
When a message is received before the timeout period expires,
a pointer to the RMr message buffer which describes the
message is returned. This will, with a high probability, be a
different message buffer than *old_msg;* the user application
should not continue to use *old_msg* after it is passed to
this function.
In the event of a timeout the return value will be the old
msg with the state set, or a nil pointer if no old message
was provided.
ERRORS
--------------------------------------------------------------------------------------------
The *state* field in the message buffer will be set to one of
the following values:
RMR_OK
The message was received without error.
RMR_ERR_BADARG
A parameter passed to the function was not valid (e.g. a
nil pointer). indicate either RMR_OK or RMR_ERR_EMPTY if
an empty message was received.
RMR_ERR_EMPTY
The message received had no associated data. The length of
the message will be 0.
RMR_ERR_NOTSUPP
The multi-threaded option was not enabled when RMr was
initialised. See the man page for *rmr_init()* for
details.
RMR_ERR_RCVFAILED
A hard error occurred preventing the receive from
completing.
When a nil pointer is returned, or any other state value was
set in the message buffer, errno will be set to one of the
following:
INVAL
Parameter(s) passed to the function were not valid.
EBADF
The underlying message transport is unable to process the
request.
ENOTSUP
The underlying message transport is unable to process the
request.
EFSM
The underlying message transport is unable to process the
request.
EAGAIN
The underlying message transport is unable to process the
request.
EINTR
The underlying message transport is unable to process the
request.
ETIMEDOUT
The underlying message transport is unable to process the
request.
ETERM
The underlying message transport is unable to process the
request.
EXAMPLE
--------------------------------------------------------------------------------------------
::
rmr_mbuf_t* mbuf = NULL; // received msg
msg = rmr_mt_recv( mr, mbuf, 100 ); // wait up to 100ms
if( msg != NULL ) {
switch( msg->state ) {
case RMR_OK:
printf( "got a good message\\n" );
break;
case RMR_ERR_EMPTY:
printf( "received timed out\\n" );
break;
default:
printf( "receive error: %d\\n", mbuf->state );
break;
}
} else {
printf( "receive timeout (nil)\\n" );
}
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
rmr_get_rcvfd(3), rmr_init(3), rmr_mk_ring(3),
rmr_mt_call(3), rmr_payload_size(3), rmr_send_msg(3),
rmr_torcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
rmr_ready(3), rmr_ring_free(3), rmr_torcv_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_payload_size
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
int rmr_payload_size( rmr_mbuf_t* msg );
DESCRIPTION
--------------------------------------------------------------------------------------------
Given a message buffer, this function returns the amount of
space (bytes) available for the user application to consume
in the message payload. This is different than the message
length available as a field in the message buffer.
RETURN VALUE
--------------------------------------------------------------------------------------------
The number of bytes available in the payload.
ERRORS
--------------------------------------------------------------------------------------------
INVAL
Parameter(s) passed to the function were not valid.
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
rmr_send_msg(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3),
rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3)
NAME
--------------------------------------------------------------------------------------------
rmr_rcv_msg
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
rmr_mbuf_t* rmr_rcv_msg( void* vctx, rmr_mbuf_t* old_msg );
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_rcv_msg function blocks until a message is received,
returning the message to the caller via a pointer to a
rmr_mbuf_t structure type. If messages were queued while
waiting for the response to a previous invocation of
rmr_call, the oldest message is removed from the queue and
returned without delay.
The *vctx* pointer is the pointer returned by the rmr_init
function. *Old_msg* is a pointer to a previously used message
buffer or NULL. The ability to reuse message buffers helps to
avoid alloc/free cycles in the user application. When no
buffer is available to supply, the receive function will
allocate one.
RETURN VALUE
--------------------------------------------------------------------------------------------
The function returns a pointer to the rmr_mbuf_t structure
which references the message information (state, length,
payload), or a NULL pointer in the case of an extreme error.
ERRORS
--------------------------------------------------------------------------------------------
The *state* field in the message buffer will indicate either
RMR_OK or RMR_ERR_EMPTY if an empty message was received. If
a nil pointer is returned, or any other state value was set
in the message buffer, errno will be set to one of the
following:
INVAL
Parameter(s) passed to the function were not valid.
EBADF
The underlying message transport is unable to process the
request.
ENOTSUP
The underlying message transport is unable to process the
request.
EFSM
The underlying message transport is unable to process the
request.
EAGAIN
The underlying message transport is unable to process the
request.
EINTR
The underlying message transport is unable to process the
request.
ETIMEDOUT
The underlying message transport is unable to process the
request.
ETERM
The underlying message transport is unable to process the
request.
EXAMPLE
--------------------------------------------------------------------------------------------
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
rmr_get_rcvfd(3), rmr_init(3), rmr_mk_ring(3),
rmr_payload_size(3), rmr_send_msg(3), rmr_torcv_msg(3),
rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
rmr_ring_free(3), rmr_torcv_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_ready
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
int rmr_ready( void* vctx );
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_ready function checks to see if a routing table has
been successfully received and installed. The return value
indicates the state of readiness.
RETURN VALUE
--------------------------------------------------------------------------------------------
A return value of 1 (true) indicates that the routing table
is in place and attempts to send messages can be made. When 0
is returned (false) the routing table has not been received
and thus attempts to send messages will fail with *no
endpoint* errors.
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
rmr_rcv_specific(3), rmr_rts_msg(3), rmr_fib(3),
rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3),
rmr_ring_free(3)
NAME
--------------------------------------------------------------------------------------------
rmr_realloc_payload
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
extern rmr_mbuf_t* rmr_realloc_payload( rmr_mbuf_t* msg, int new_len, int copy, int clone );
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_realloc_payload function will return a pointer to an
RMR message buffer struct (rmr_mbuf_t) which has a payload
large enough to accomodate *new_len* bytes. If necessary, the
underlying payload is reallocated, and the bytes from the
original payload are copied if the *copy* parameter is true
(1). If the message passed in has a payload large enough,
there is no additional memory allocation and copying.
Cloning The Message Buffer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This function can also be used to generate a separate copy of
the original message, with the desired payload size, without
destroying the original message buffer or the original
payload. A standalone copy is made only when the *clone*
parameter is true (1). When cloning, the payload is copied to
the cloned message **only** if the *copy* parameter is true.
Message Buffer Metadata
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The metadata in the original message buffer (message type,
subscription ID, and payload length) will be preserved if the
*copy* parameter is true. When this parameter is not true
(0), then these values are set to the uninitialised value
(-1) for type and ID, and the length is set to 0.
RETURN VALUE
--------------------------------------------------------------------------------------------
The rmr_realloc_payload function returns a pointer to the
message buffer with the payload which is large enough to hold
*new_len* bytes. If the *clone* option is true, this will be
a pointer to the newly cloned message buffer; the original
message buffer pointer may still be used to referenced that
message. It is the calling application's responsibility to
free the memory associateed with both messages using the
rmr_free_msg() function.
When the *clone* option is not used, it is still good
practice by the calling application to capture and use this
reference as it is possible that the message buffer, and not
just the payload buffer, was reallocated. In the event of an
error, a nil pointer will be returned and the value of
*errno* will be set to reflect the problem.
ERRORS
--------------------------------------------------------------------------------------------
These value of *errno* will reflect the error condition if a
nil pointer is returned:
ENOMEM
Memory allocation of the new payload failed.
EINVAL
The pointer passed in was nil, or refrenced an invalid
message, or the required length was not valid.
EXAMPLE
--------------------------------------------------------------------------------------------
The following code bit illustrates how this function can be
used to reallocate a buffer for a return to sender
acknowledgement message which is larger than the message
received.
::
if( rmr_payload_size( msg ) < ack_sz ) { // received message too small for ack
msg = rmr_realloc_payload( msg, ack_sz, 0, 0 ); // reallocate the message with a payload big enough
if( msg == NULL ) {
fprintf( stderr, "[ERR] realloc returned a nil pointer: %s\\n", strerror( errno ) );
} else {
} e// populate and send ack message
}}
}
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_free_msg(3), rmr_init(3),
rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
rmr_fib(3), rmr_has_str(3), rmr_set_stimeout(3),
rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3)
NAME
--------------------------------------------------------------------------------------------
rmr_rts_msg
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
rmr_mbuf_t* rmr_rts_msg( void* vctx, rmr_mbuf_t* msg );
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_rts_msg function sends a message returning it to the
endpoint which sent the message rather than selecting an
endpoint based on the message type and routing table. Other
than this small difference, the behaviour is exactly the same
as rmr_send_msg.
Retries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The send operations in RMr will retry *soft* send failures
until one of three conditions occurs:
1.
The message is sent without error
2.
The underlying transport reports a * hard * failure
3.
The maximum number of retry loops has been attempted
A retry loop consists of approximately 1000 send attemps **
without** any intervening calls to * sleep() * or * usleep().
* The number of retry loops defaults to 1, thus a maximum of
1000 send attempts is performed before returning to the user
application. This value can be set at any point after RMr
initialisation using the * rmr_set_stimeout() * function
allowing the user application to completely disable retires
(set to 0), or to increase the number of retry loops.
Transport Level Blocking
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The underlying transport mechanism used to send messages is
configured in *non-blocking* mode. This means that if a
message cannot be sent immediately the transport mechanism
will **not** pause with the assumption that the inability to
send will clear quickly (within a few milliseconds). This
means that when the retry loop is completely disabled (set to
0), that the failure to accept a message for sending by the
underlying mechanisms (software or hardware) will be reported
immediately to the user application.
It should be noted that depending on the underlying transport
mechanism being used, it is extremly possible that during
normal operations that retry conditions are very likely to
happen. These are completely out of RMr's control, and there
is nothing that RMr can do to avoid or midigate these other
than by allowing RMr to retry the send operation, and even
then it is possible (e.g. during connection reattempts), that
a single retry loop is not enough to guarentee a successful
send.
PAYLOAD SIZE
--------------------------------------------------------------------------------------------
When crafting a response based on a received message, the
user application must take care not to write more bytes to
the message payload than the allocated message has. In the
case of a received message, it is possible that the response
needs to be larger than the payload associated with the
inbound message. In order to use the return to sender
function, the source infomration in the orignal message must
be present in the response; information which cannot be added
to a message buffer allocated through the standard RMR
allocation function. To allocate a buffer with a larger
payload, and which retains the necessary sender data needed
by this function, the *rmr_realloc_payload()* function must
be used to extend the payload to a size suitable for the
response.
RETURN VALUE
--------------------------------------------------------------------------------------------
On success, a new message buffer, with an empty payload, is
returned for the application to use for the next send. The
state in this buffer will reflect the overall send operation
state and should be RMR_OK.
If the state in the returned buffer is anything other than
UT_OK, the user application may need to attempt a
retransmission of the message, or take other action depending
on the setting of errno as described below.
In the event of extreme failure, a NULL pointer is returned.
In this case the value of errno might be of some use, for
documentation, but there will be little that the user
application can do other than to move on.
ERRORS
--------------------------------------------------------------------------------------------
The following values may be passed back in the *state* field
of the returned message buffer.
RMR_ERR_BADARG
The message buffer pointer did not refer to a valid
message.
RMR_ERR_NOHDR
The header in the message buffer was not valid or
corrupted.
RMR_ERR_NOENDPT
The message type in the message buffer did not map to a
known endpoint.
RMR_ERR_SENDFAILED
The send failed; errno has the possible reason.
The following values may be assigned to errno on failure.
INVAL
Parameter(s) passed to the function were not valid, or the
underlying message processing environment was unable to
interpret the message.
ENOKEY
The header information in the message buffer was invalid.
ENXIO
No known endpoint for the message could be found.
EMSGSIZE
The underlying transport refused to accept the message
because of a size value issue (message was not attempted
to be sent).
EFAULT
The message referenced by the message buffer is corrupt
(NULL pointer or bad internal length).
EBADF
Internal RMR error; information provided to the message
transport environment was not valid.
ENOTSUP
Sending was not supported by the underlying message
transport.
EFSM
The device is not in a state that can accept the message.
EAGAIN
The device is not able to accept a message for sending.
The user application should attempt to resend.
EINTR
The operation was interrupted by delivery of a signal
before the message was sent.
ETIMEDOUT
The underlying message environment timed out during the
send process.
ETERM
The underlying message environment is in a shutdown state.
EXAMPLE
--------------------------------------------------------------------------------------------
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
rmr_rcv_specific(3), rmr_ready(3), rmr_fib(3),
rmr_has_str(3), rmr_set_stimeout(3), rmr_tokenise(3),
rmr_mk_ring(3), rmr_ring_free(3)
NAME
--------------------------------------------------------------------------------------------
rmr_send_msg
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
rmr_mbuf_t* rmr_send_msg( void* vctx, rmr_mbuf_t* msg );
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_send_msg function accepts a message buffer from the
user application and attempts to send it. The destination of
the message is selected based on the message type specified
in the message buffer, and the matching information in the
routing tables which are currently in use by the RMR library.
This may actually result in the sending of the message to
multiple destinations which could degrade expected overall
performance of the user application. (Limiting excessive
sending of messages is the responsibility of the
application(s) responsible for building the routing table
used by the RMR library, and not the responsibility of the
library.)
Retries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The send operations in RMr will retry *soft* send failures
until one of three conditions occurs:
1.
The message is sent without error
2.
The underlying transport reports a * hard * failure
3.
The maximum number of retry loops has been attempted
A retry loop consists of approximately 1000 send attemps **
without** any intervening calls to * sleep() * or * usleep().
* The number of retry loops defaults to 1, thus a maximum of
1000 send attempts is performed before returning to the user
application. This value can be set at any point after RMr
initialisation using the * rmr_set_stimeout() * function
allowing the user application to completely disable retires
(set to 0), or to increase the number of retry loops.
Transport Level Blocking
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The underlying transport mechanism used to send messages is
configured in *non-blocking* mode. This means that if a
message cannot be sent immediately the transport mechanism
will **not** pause with the assumption that the inability to
send will clear quickly (within a few milliseconds). This
means that when the retry loop is completely disabled (set to
0), that the failure to accept a message for sending by the
underlying mechanisms (software or hardware) will be reported
immediately to the user application.
It should be noted that depending on the underlying transport
mechanism being used, it is extremly possible that during
normal operations that retry conditions are very likely to
happen. These are completely out of RMr's control, and there
is nothing that RMr can do to avoid or midigate these other
than by allowing RMr to retry the send operation, and even
then it is possible (e.g. during connection reattempts), that
a single retry loop is not enough to guarentee a successful
send.
RETURN VALUE
--------------------------------------------------------------------------------------------
On success, a new message buffer, with an empty payload, is
returned for the application to use for the next send. The
state in this buffer will reflect the overall send operation
state and should be RMR_OK.
When the message cannot be successfully sent this function
will return the unsent (original) message buffer with the
state set to indicate the reason for failure. The value of
*errno* may also be set to reflect a more detailed failure
reason if it is known.
In the event of extreme failure, a NULL pointer is returned.
In this case the value of errno might be of some use, for
documentation, but there will be little that the user
application can do other than to move on.
ERRORS
--------------------------------------------------------------------------------------------
The following values may be passed back in the *state* field
of the returned message buffer.
RMR_RETRY
The message could not be sent, but the underlying
transport mechanism indicates that the failure is
temporary. If the send operation is tried again it might
be successful.
RMR_SEND_FAILED
The send operation was not successful and the underlying
transport mechanism indicates a permanent (hard) failure;
retrying the send is not possible.
RMR_ERR_BADARG
The message buffer pointer did not refer to a valid
message.
RMR_ERR_NOHDR
The header in the message buffer was not valid or
corrupted.
RMR_ERR_NOENDPT
The message type in the message buffer did not map to a
known endpoint.
The following values may be assigned to errno on failure.
INVAL
Parameter(s) passed to the function were not valid, or the
underlying message processing environment was unable to
interpret the message.
ENOKEY
The header information in the message buffer was invalid.
ENXIO
No known endpoint for the message could be found.
EMSGSIZE
The underlying transport refused to accept the message
because of a size value issue (message was not attempted
to be sent).
EFAULT
The message referenced by the message buffer is corrupt
(NULL pointer or bad internal length).
EBADF
Internal RMR error; information provided to the message
transport environment was not valid.
ENOTSUP
Sending was not supported by the underlying message
transport.
EFSM
The device is not in a state that can accept the message.
EAGAIN
The device is not able to accept a message for sending.
The user application should attempt to resend.
EINTR
The operation was interrupted by delivery of a signal
before the message was sent.
ETIMEDOUT
The underlying message environment timed out during the
send process.
ETERM
The underlying message environment is in a shutdown state.
EXAMPLE
--------------------------------------------------------------------------------------------
The following is a simple example of how the rmr_send_msg
function is called. In this example, the send message buffer
is saved between calls and reused eliminating alloc/free
cycles.
::
static rmr_mbuf_t* send_msg = NULL; // message to send; reused on each call
msg_t* send_pm; // payload for send
msg_t* pm; // our message format in the received payload
mif( send_msg == NULL ) {
send_msg = rmr_alloc_msg( mr, MAX_SIZE ); r// new buffer to send
}
// reference payload and fill in message type
pm = (msg_t*) send_msg->payload;
send_msg->mtype = MT_ANSWER;
msg->len = generate_data( pm ); e// something that fills the payload in
msg = rmr_send_msg( mr, send_msg );
mif( ! msg ) {
m !return ERROR;
m} else {
m sif( msg->state != RMR_OK ) {
m s m// check for eagain, and resend if needed
m s m// else return error
m s}
m}
mreturn OK;
m r ;
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
rmr_payload_size(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
rmr_rts_msg(3), rmr_ready(3), rmr_mk_ring(3),
rmr_ring_free(3), rmr_torcv_rcv(3), rmr_wh_send_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_set_stimeout
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
rmr_mbuf_t* rmr_set_stimeout( void* vctx, int rloops );
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_set_stimeout function sets the configuration for how
RMr will retry message send operations which complete with
either a *timeout* or *again* completion value. (Send
operations include all of the possible message send
functions: *rmr_send_msg(), rmr_call(), rmr_rts_msg()* and
*rmr_wh_send_msg().* The *rloops* parameter sets the maximum
number of retry loops that will be attempted before giving up
and returning the unsuccessful state to the user application.
Each retry loop is approximately 1000 attempts, and RMr does
**not** invoke any sleep function between retries in the
loop; a small, 1 mu-sec, sleep is executed between loop sets
if the *rloops* value is greater than 1.
Disabling Retries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
By default, the send operations will execute with an *rloop*
setting of 1; each send operation will attempt to resend the
message approximately 1000 times before giving up. If the
user application does not want to have send operations retry
when the underlying transport mechanism indicates *timeout*
or *again,* the application should invoke this function and
pass a value of 0 (zero) for *rloops.* With this setting, all
RMr send operations will attempt a send operation only
**once,** returning immediately to the caller with the state
of that single attempt.
RETURN VALUE
--------------------------------------------------------------------------------------------
This function returns a -1 to indicate that the *rloops*
value could not be set, and the value *RMR_OK* to indicate
success.
ERRORS
--------------------------------------------------------------------------------------------
Currently errno is **not** set by this function; the only
cause of a failure is an invalid context (*vctx*) pointer.
EXAMPLE
--------------------------------------------------------------------------------------------
The following is a simple example of how the rmr_set_stimeout
function is called.
::
#define NO_FLAGS 0
char* Oport = "43086"; // port for message router listen
int rmax_size = 4096; // max message size for default allocations
void* mr_context; // message router context
mr_context = rmr_init( port, max_size, NO_FLAGS );
if( mr_context != NULL ) {
rmr_set_stimeout( mr_context, 0 ); // turn off retries
}
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
rmr_payload_size(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
rmr_rts_msg(3), rmr_ready(3), rmr_mk_ring(3),
rmr_ring_free(3), rmr_send_msg(3), rmr_torcv_rcv(3),
rmr_wh_send_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_set_trace
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
int rmr_bytes2payload( rmr_mbuf_t* mbuf, unsigned char* data, int len )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_set_trace function will copy len bytes from data into
the trace portion of mbuf. If the trace area of mbuf is not
the correct size, the message buffer will be reallocated to
ensure that enough space is available for the trace data.
RETURN VALUE
--------------------------------------------------------------------------------------------
The rmr_set_trace function returns the number of bytes
successfully copied to the message. If 0 is returned either
the message pointer was nil, or the size in the parameters
was <= 0.
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_tralloc_msg(3), rmr_bytes2xact(3),
rmr_bytes2payload(3), rmr_call(3), rmr_free_msg(3),
rmr_get_rcvfd(3), rmr_get_meid(3), rmr_get_trace(3),
rmr_get_trlen(3), rmr_init(3), rmr_init_trace(3),
rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3),
rmr_ring_free(3), rmr_str2meid(3), rmr_str2xact(3),
rmr_wh_open(3), rmr_wh_send_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_str2meid
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
int rmr_str2meid( rmr_mbuf_t* mbuf, unsigned char* src, int len )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_str2meid function will copy the string pointed to by
src to the managed entity ID (meid) field in the given
message. The field is a fixed length, gated by the constant
RMR_MAX_MEID and if string length is larger than this value,
then **nothing** will be copied. (Note, this differs slightly
from the behaviour of the lrmr_bytes2meid() function.)
RETURN VALUE
--------------------------------------------------------------------------------------------
On success, the value RMR_OK is returned. If the string
cannot be copied to the message, the return value will be one
of the errors listed below.
ERRORS
--------------------------------------------------------------------------------------------
If the return value is not RMR_OK, then it will be set to one
of the values below.
RMR_ERR_BADARG
The message, or an internal portion of the message, was
corrupted or the pointer was invalid.
RMR_ERR_OVERFLOW
The length passed in was larger than the maximum length of
the field; only a portion of the source bytes were copied.
EXAMPLE
--------------------------------------------------------------------------------------------
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
rmr_get_meid(3), rmr_get_rcvfd(3), rmr_payload_size(3),
rmr_send_msg(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3),
rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3),
rmr_bytes2meid(3), rmr_wh_open(3), rmr_wh_send_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_str2xact
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
int rmr_str2xact( rmr_mbuf_t* mbuf, unsigned char* src, int len )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_str2xact function will copy the string pointed to by
src to the transaction ID (xaction) field in the given
message. The field is a fixed length, gated by the constant
RMR_MAX_XID and if string length is larger than this value,
then **nothing** will be copied. (Note, this differs slightly
from the behaviour of the lrmr_bytes2xact() function.)
RETURN VALUE
--------------------------------------------------------------------------------------------
On success, the value RMR_OK is returned. If the string
cannot be copied to the message, the return value will be
one of the errors listed below.
ERRORS
--------------------------------------------------------------------------------------------
If the return value is not RMR_OK, then it will be set to
one of the values below.
RMR_ERR_BADARG
The message, or an internal portion of the message, was
corrupted or the pointer was invalid.
RMR_ERR_OVERFLOW
The length passed in was larger than the maximum length of
the field; only a portion of the source bytes were copied.
EXAMPLE
--------------------------------------------------------------------------------------------
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_bytes2meid(3), rmr_bytes2xact(3),
rmr_call(3), rmr_free_msg(3), rmr_get_meid(3),
rmr_get_rcvfd(3), rmr_get_xact(3), rmr_payload_size(3),
rmr_send_msg(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3),
rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3),
rmr_str2meid(3), rmr_wh_open(3), rmr_wh_send_msg(3)
NAME
--------------------------------------------------------------------------------------------
RMR support functions
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
#include <rmr/ring_inline.h>
char* rmr_fib( char* fname );
int rmr_has_str( char const* buf, char const* str, char sep, int max );
int rmr_tokenise( char* buf, char** tokens, int max, char sep );
void* rmr_mk_ring( int size );
void rmr_ring_free( void* vr );
static inline void* rmr_ring_extract( void* vr )
static inline int rmr_ring_insert( void* vr, void* new_data )
DESCRIPTION
--------------------------------------------------------------------------------------------
These functions support the RMR library, and are made
available to user applications as some (e.g. route table
generators) might need and/or want to make use of them. The
rmr_fib function accepts a file name and reads the entire
file into a single buffer. The intent is to provide an easy
way to load a static route table without a lot of buffered
I/O hoops.
The rmr_has_str function accepts a *buffer* containing a set
of delimited tokens (e.g. foo,bar,goo) and returns true if
the target string, *str,* matches one of the tokens. The
*sep* parameter provides the separation character in the
buffer (e.g a comma) and *max* indicates the maximum number
of tokens to split the buffer into before checking.
The rmr_tokenise function is a simple tokeniser which splits
*buf* into tokens at each occurrence of *sep*. Multiple
occurrences of the separator character (e.g. a,,b) result in
a nil token. Pointers to the tokens are placed into the
*tokens* array provided by the caller which is assumed to
have at least enough space for *max* entries.
The rmr_mk_ring function creates a buffer ring with *size*
entries.
The rmr_ring_free function accepts a pointer to a ring
context and frees the associated memory.
The rmr_ring_insert and rmr_ring_extract functions are
provided as static inline functions via the
*rmr/ring_inline.h* header file. These functions both accept
the ring *context* returned by mk_ring, and either insert a
pointer at the next available slot (tail) or extract the data
at the head.
RETURN VALUES
--------------------------------------------------------------------------------------------
The following are the return values for each of these
functions.
The rmr_fib function returns a pointer to the buffer
containing the contents of the file. The buffer is terminated
with a single nil character (0) making it a legitimate C
string. If the file was empty or nonexistent, a buffer with
an immediate nil character. If it is important to the calling
programme to know if the file was empty or did not exist, the
caller should use the system stat function call to make that
determination.
The rmr_has_str function returns 1 if *buf* contains the
token referenced by &ita and false (0) if it does not. On
error, a -1 value is returned and errno is set accordingly.
The rmr_tokenise function returns the actual number of token
pointers placed into *tokens*
The rmr_mk_ring function returns a void pointer which is the
*context* for the ring.
The rmr_ring_insert function returns 1 if the data was
successfully inserted into the ring, and 0 if the ring is
full and the pointer could not be deposited.
The rmr_ring_extract will return the data which is at the
head of the ring, or NULL if the ring is empty.
ERRORS
--------------------------------------------------------------------------------------------
Not many of these functions set the value in errno, however
the value may be one of the following:
INVAL
Parameter(s) passed to the function were not valid.
EXAMPLE
--------------------------------------------------------------------------------------------
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
NAME
--------------------------------------------------------------------------------------------
rmr_torcv_msg
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
rmr_mbuf_t* rmr_torcv_msg( void* vctx, rmr_mbuf_t* old_msg, int ms_to );
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_torcv_msg function will pause for *ms_to*
milliseconds waiting for a message to arrive. If a message
arrives before the timeout expires the message buffer
returned will have a status of RMR_OK and the payload will
contain the data received. If the timeout expires before the
message is received, the status will have the value
RMR_ERR_TIMEOUT. When a received message is returned the
message buffer will also contain the message type and length
set by the sender. If messages were queued while waiting for
the response to a previous invocation of rmr_call, the oldest
message is removed from the queue and returned without delay.
The *vctx* pointer is the pointer returned by the rmr_init
function. *Old_msg* is a pointer to a previously used message
buffer or NULL. The ability to reuse message buffers helps to
avoid alloc/free cycles in the user application. When no
buffer is available to supply, the receive function will
allocate one.
RETURN VALUE
--------------------------------------------------------------------------------------------
The function returns a pointer to the rmr_mbuf_t structure
which references the message information (state, length,
payload), or a NULL pointer in the case of an extreme error.
ERRORS
--------------------------------------------------------------------------------------------
The *state* field in the message buffer will be one of the
following:
RMR_OK
The message buffer (payload) references the received data.
RMR_ERR_INITFAILED
The first call to this function must initialise an
underlying system notification mechanism. On failure, this
error is returned and errno will have the system error
status set. If this function fails to intialise, the poll
mechansim, it is likely that message receives will never
be successful.
RMR_ERR_TIMEOUT
The timeout expired before a complete message was
received. All other fields in the message buffer are not
valid.
RMR_ERR_EMPTY
A message was received, but it had no payload. All other
fields in the message buffer are not valid.
INVAL
Parameter(s) passed to the function were not valid.
EBADF
The underlying message transport is unable to process the
request.
ENOTSUP
The underlying message transport is unable to process the
request.
EFSM
The underlying message transport is unable to process the
request.
EAGAIN
The underlying message transport is unable to process the
request.
EINTR
The underlying message transport is unable to process the
request.
ETIMEDOUT
The underlying message transport is unable to process the
request.
ETERM
The underlying message transport is unable to process the
request.
EXAMPLE
--------------------------------------------------------------------------------------------
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
rmr_get_rcvfd(3), rmr_init(3), rmr_payload_size(3),
rmr_rcv_msg(3), rmr_send_msg(3), rmr_rcv_specific(3),
rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3),
rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3)
NAME
--------------------------------------------------------------------------------------------
rmr_trace_ref
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
int rmr_trace_ref( rmr_mbuf_t* mbuf, int* sizeptr )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_trace_ref function return a pointer to the trace area
in the message, and optionally populate the user programme
supplied size integer with the trace area size, if *sizeptr*
is not nil.
RETURN VALUE
--------------------------------------------------------------------------------------------
On success, a void pointer to the trace area of the message
is returned. A nil pointer is returned if the message has no
trace data area allocated, or if the message itself is
invalid.
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_tralloc_msg(3), rmr_bytes2xact(3),
rmr_bytes2meid(3), rmr_call(3), rmr_free_msg(3),
rmr_get_rcvfd(3), rmr_get_trlen(3), rmr_init(3),
rmr_init_trace(3), rmr_payload_size(3), rmr_send_msg(3),
rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3),
rmr_set_trace(3)
NAME
--------------------------------------------------------------------------------------------
rmr_tralloc_msg
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
rmr_mbuf_t* rmr_tralloc_msg( void* vctx, int size,
int trace_size, unsigned const char *tr_data );
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_alloc_msg function is used to allocate a buffer which
the user programme can write into and then send through the a
library. The buffer is allocated such that sending it
requires no additional copying from the buffer as it passes
through the underlying transport mechanism.
The *size* parameter is used to set the payload length in the
message and If it is 0, then the default size supplied on the
*rmr_init* call will be used. In addition to allocating the
payload, a space in the buffer is reserved for *trace* data
(tr_size bytes), and the bytes pointed to by *tr_data* are
copied into that portion of the message. The *vctx* parameter
is the void context pointer that was returned by the
*rmr_init* function.
The pointer to the message buffer returned is a structure
which has some user application visible fields; the structure
is described in rmr.h, and is illustrated below.
::
typedef struct {
int state;
int mtype;
int len;
unsigned char* payload;
unsigned char* xaction;
} rmr_mbuf_t;
state
Is the current buffer state. Following a call to
rmr_send_msg the state indicates whether the buffer was
successfully sent which determines exactly what the
payload points to. If the send failed, the payload
referenced by the buffer is the message that failed to
send (allowing the application to attempt a
retransmission). When the state is a_OK the buffer
represents an empty buffer that the application may fill
in in preparation to send.
mtype
When sending a message, the application is expected to set
this field to the appropriate message type value (as
determined by the user programme). Upon send this value
determines how the a library will route the message. For a
buffer which has been received, this field will contain
the message type that was set by the sending application.
len
The application using a buffer to send a message is
expected to set the length value to the actual number of
bytes that it placed into the message. This is likely less
than the total number of bytes that the message can carry.
For a message buffer that is passed to the application as
the result of a receive call, this will be the value that
the sending application supplied and should indicate the
number of bytes in the payload which are valid.
payload
The payload is a pointer to the actual received data. The
user programme may read and write from/to the memory
referenced by the payload up until the point in time that
the buffer is used on a rmr_send, rmr_call or rmr_reply
function call. Once the buffer has been passed back to a a
library function the user programme should **NOT** make
use of the payload pointer.
xaction
The *xaction* field is a pointer to a fixed sized area in
the message into which the user may write a transaction
ID. The ID is optional with the exception of when the user
application uses the rmr_call function to send a message
and wait for the reply; the underlying a processing
expects that the matching reply message will also contain
the same data in the *xaction* field.
RETURN VALUE
--------------------------------------------------------------------------------------------
The function returns a pointer to a rmr_mbuf structure, or
NULL on error.
ERRORS
--------------------------------------------------------------------------------------------
ENOMEM
Unable to allocate memory.
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_mbuf(3) rmr_call(3), rmr_free_msg(3),
rmr_init(3), rmr_init_trace(3), rmr_get_trace(3),
rmr_get_trlen(3), rmr_payload_size(3), rmr_send_msg(3),
rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
rmr_mk_ring(3), rmr_ring_free(3), rmr_set_trace(3)
NAME
--------------------------------------------------------------------------------------------
rmr_wh_open
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
void rmr_close( void* vctx, rmr_whid_t whid )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_wh_close function closes the wormhole associated with
the wormhole id passed in. Future calls to rmr_wh_send_msg
with this ID will fail.
The underlying TCP connection to the remote endpoint is
**not** closed as this session may be reqruired for
regularlly routed messages (messages routed based on message
type). There is no way to force a TCP session to be closed at
this point in time.
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
rmr_get_rcvfd(3), rmr_payload_size(3), rmr_send_msg(3),
rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
rmr_mk_ring(3), rmr_ring_free(3), rmr_wh_open(3),
rmr_wh_send_msg(3)
NAME
--------------------------------------------------------------------------------------------
rmr_wh_open
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
void* rmr_wh_open( void* vctx, char* target )
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_wh_open function creates a direct link for sending, a
wormhole, to another RMr based process. Sending messages
through a wormhole requires that the connection be
established overtly by the user application (via this
function), and that the ID returned by rmr_wh_open be passed
to the rmr_wh_send_msg function.
*Target* is the *name* or *IP-address* combination of the
processess that the wormhole should be connected to. *Vctx*
is the RMr void context pointer that was returned by the
rmr_init function.
When invoked, this function immediatly attempts to connect to
the target process. If the connection cannot be established,
an error is returned to the caller, and no direct messages
can be sent to the target. Once a wormhole is connected, the
underlying transport mechanism (e.g. NNG) will provide
reconnects should the connection be lost, however the
handling of messages sent when a connection is broken is
undetermined as each underlying transport mechanism may
handle buffering and retries differently.
RETURN VALUE
--------------------------------------------------------------------------------------------
The rmr_wh_open function returns a type rmr_whid_t which must
be passed to the rmr_wh_send_msg function when sending a
message. The id may also be tested to determine success or
failure of the connection by using the RMR_WH_CONNECTED macro
and passing the ID as the parameter; a result of 1 indicates
that the connection was esablished and that the ID is valid.
ERRORS
--------------------------------------------------------------------------------------------
The following error values are specifically set by this RMR
function. In some cases the error message of a system call is
propagated up, and thus this list might be incomplete.
EINVAL
A parameter passed was not valid.
EACCESS
The user applicarion does not have the ability to
establish a wormhole to the indicated target (or maybe any
target).
ECONNREFUSED
The connection was refused.
EXAMPLE
--------------------------------------------------------------------------------------------
::
void* rmc;
rmr_whid_t wh;
rmc = rmr_init( "43086", 4096, 0 ); // init context
wh = rmr_wh_open( rmc, "localhost:6123" );
if( !RMR_WH_CONNECTED( wh ) ) {
f fprintf( stderr, "unable to connect wormhole: %s\\n",
strerror( errno ) );
}
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
rmr_get_rcvfd(3), rmr_payload_size(3), rmr_send_msg(3),
rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
rmr_mk_ring(3), rmr_ring_free(3), rmr_wh_send_msg(3),
rmr_wh_close(3)
NAME
--------------------------------------------------------------------------------------------
rmr_wh_send_msg
SYNOPSIS
--------------------------------------------------------------------------------------------
::
#include <rmr/rmr.h>
rmr_mbuf_t* rmr_wh_send_msg( void* vctx, rmr_whid_t id, rmr_mbuf_t* msg );
DESCRIPTION
--------------------------------------------------------------------------------------------
The rmr_wh_send_msg function accepts a message buffer from
the user application and attempts to send it using the
wormhole ID provided (id). Unlike *rmr_send_msg,* this
function attempts to send the message directly to a process
at the other end of a wormhole which was created with
*rmr_wh-open().* When sending message via wormholes, the
normal RMr routing based on message type is ignored, and the
caller may leave the message type unspecified in the message
buffer (unless it is needed by the receiving process).
The message buffer (msg) used to send is the same format as
used for regular RMr send and reply to sender operations,
thus any buffer allocated by these means, or calls to
*rmr_rcv_msg()* can be passed to this function.
Retries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The send operations in RMr will retry *soft* send failures
until one of three conditions occurs:
1.
The message is sent without error
2.
The underlying transport reports a * hard * failure
3.
The maximum number of retry loops has been attempted
A retry loop consists of approximately 1000 send attemps **
without** any intervening calls to * sleep() * or * usleep().
* The number of retry loops defaults to 1, thus a maximum of
1000 send attempts is performed before returning to the user
application. This value can be set at any point after RMr
initialisation using the * rmr_set_stimeout() * function
allowing the user application to completely disable retires
(set to 0), or to increase the number of retry loops.
Transport Level Blocking
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The underlying transport mechanism used to send messages is
configured in *non-blocking* mode. This means that if a
message cannot be sent immediately the transport mechanism
will **not** pause with the assumption that the inability to
send will clear quickly (within a few milliseconds). This
means that when the retry loop is completely disabled (set to
0), that the failure to accept a message for sending by the
underlying mechanisms (software or hardware) will be reported
immediately to the user application.
It should be noted that depending on the underlying transport
mechanism being used, it is extremly possible that during
normal operations that retry conditions are very likely to
happen. These are completely out of RMr's control, and there
is nothing that RMr can do to avoid or midigate these other
than by allowing RMr to retry the send operation, and even
then it is possible (e.g. during connection reattempts), that
a single retry loop is not enough to guarentee a successful
send.
RETURN VALUE
--------------------------------------------------------------------------------------------
On success, a new message buffer, with an empty payload, is
returned for the application to use for the next send. The
state in this buffer will reflect the overall send operation
state and should be RMR_OK.
If the state in the returned buffer is anything other than
RMR_OK, the user application may need to attempt a
retransmission of the message, or take other action depending
on the setting of errno as described below.
In the event of extreme failure, a NULL pointer is returned.
In this case the value of errno might be of some use, for
documentation, but there will be little that the user
application can do other than to move on.
ERRORS
--------------------------------------------------------------------------------------------
The following values may be passed back in the *state* field
of the returned message buffer.
RMR_ERR_WHID
The wormhole ID passed in was not associated with an open
wormhole, or was out of range for a valid ID.
RMR_ERR_NOWHOPEN
No wormholes exist, further attempt to validate the ID are
skipped.
RMR_ERR_BADARG
The message buffer pointer did not refer to a valid
message.
RMR_ERR_NOHDR
The header in the message buffer was not valid or
corrupted.
The following values may be assigned to errno on failure.
INVAL
Parameter(s) passed to the function were not valid, or the
underlying message processing environment was unable to
interpret the message.
ENOKEY
The header information in the message buffer was invalid.
ENXIO
No known endpoint for the message could be found.
EMSGSIZE
The underlying transport refused to accept the message
because of a size value issue (message was not attempted
to be sent).
EFAULT
The message referenced by the message buffer is corrupt
(NULL pointer or bad internal length).
EBADF
Internal RMR error; information provided to the message
transport environment was not valid.
ENOTSUP
Sending was not supported by the underlying message
transport.
EFSM
The device is not in a state that can accept the message.
EAGAIN
The device is not able to accept a message for sending.
The user application should attempt to resend.
EINTR
The operation was interrupted by delivery of a signal
before the message was sent.
ETIMEDOUT
The underlying message environment timed out during the
send process.
ETERM
The underlying message environment is in a shutdown state.
EXAMPLE
--------------------------------------------------------------------------------------------
The following is a simple example of how the a wormhole is
created (rmr_wh_open) and then how rmr_wh_send_msg function
is used to send messages. Some error checking is omitted for
clarity.
::
#include <rmr/rmr.h> .// system headers omitted for clarity
int main() {
rmr_whid_t whid = -1; // wormhole id for sending
void* mrc; //msg router context
int i;
rmr_mbuf_t* sbuf; // send buffer
int count = 0;
mrc = rmr_init( "43086", RMR_MAX_RCV_BYTES, RMRFL_NONE );
if( mrc == NULL ) {
fprintf( stderr, "[FAIL] unable to initialise RMr environment\\n" );
exit( 1 );
}
while( ! rmr_ready( mrc ) ) { e i// wait for routing table info
sleep( 1 );
}
sbuf = rmr_alloc_msg( mrc, 2048 );
while( 1 ) {
if( whid < 0 ) {
whid = rmr_wh_open( mrc, "localhost:6123" ); // open fails if endpoint refuses conn
w if( RMR_WH_CONNECTED( wh ) ) {
snprintf( sbuf->payload, 1024, "periodic update from sender: %d", count++ );
sbuf->len = strlen( sbuf->payload );
sbuf = rmr_wh_send_msg( mrc, whid, sbuf );
}
}
sleep( 5 );
}
}
SEE ALSO
--------------------------------------------------------------------------------------------
rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
rmr_payload_size(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3),
rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3),
rmr_set_stimeout(3), rmr_wh_open(3), rmr_wh_close(3)