-
-
-.. 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.
-
-
-============================================================================================
-Man Page: rmr_mt_call
-============================================================================================
-
-RMR Library Functions
-============================================================================================
-
-
-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 the order received, one per call to
-rmr_rcv_msg.
-
-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 attempts
-**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 extremely likely that retry
-conditions will happen during normal operations. These are
-completely out of RMR's control, and there is nothing that
-RMR can do to avoid or mitigate 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 guarantee 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; // appl message struct (payload)
- // get a send buffer and reference the payload
- mbuf = rmr_alloc_msg( mr, sizeof( pm->req ) );
- pm = (msg_t*) mbuf->payload;
- // 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 ); // 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)
+.. 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.
+
+============================================================================================
+Man Page: rmr_mt_call
+============================================================================================
+
+
+
+
+RMR LIBRARY FUNCTIONS
+=====================
+
+
+
+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 the order received, one per
+call to ``rmr_rcv_msg.``
+
+
+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:
+
+
+* The message is sent without error
+
+* The underlying transport reports a *hard* failure
+
+* The maximum number of retry loops has been attempted
+
+
+A retry loop consists of approximately 1000 send attempts
+**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 extremely likely that retry
+conditions will happen during normal operations. These are
+completely out of RMR's control, and there is nothing that
+RMR can do to avoid or mitigate 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 guarantee 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.
+
+
+ .. list-table::
+ :widths: auto
+ :header-rows: 0
+ :class: borderless
+
+ * - **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.
+
+
+ .. list-table::
+ :widths: auto
+ :header-rows: 0
+ :class: borderless
+
+ * - **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; // appl message struct (payload)
+
+ // get a send buffer and reference the payload
+ mbuf = rmr_alloc_msg( mr, sizeof( pm->req ) );
+ pm = (msg_t*) mbuf->payload;
+
+ // 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 ); // 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)