1 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
2 .. SPDX-License-Identifier: CC-BY-4.0
3 .. CAUTION: this document is generated from source in doc/src/rtd.
4 .. To make changes edit the source and recompile the document.
5 .. Do NOT make changes directly to .rst or .md files.
7 ============================================================================================
8 Man Page: rmr_wh_send_msg
9 ============================================================================================
33 rmr_mbuf_t* rmr_wh_send_msg( void* vctx, rmr_whid_t id, rmr_mbuf_t* msg )
40 The ``rmr_wh_send_msg`` function accepts a message buffer
41 from the user application and attempts to send it using the
42 wormhole ID provided (id). Unlike *rmr_send_msg,* this
43 function attempts to send the message directly to a process
44 at the other end of a wormhole which was created with
45 *rmr_wh_open().* When sending message via wormholes, the
46 normal RMR routing based on message type is ignored, and the
47 caller may leave the message type unspecified in the message
48 buffer (unless it is needed by the receiving process).
50 *Vctx* is the RMR void context pointer that was returned by
51 the ``rmr_init`` function. The message buffer (msg) used to
52 send is the same format as used for regular RMR send and
53 reply to sender operations, thus any buffer allocated by
54 these means, or calls to *rmr_rcv_msg()* can be passed to
61 The send operations in RMR will retry *soft* send failures
62 until one of three conditions occurs:
65 * The message is sent without error
67 * The underlying transport reports a *hard* failure
69 * The maximum number of retry loops has been attempted
72 A retry loop consists of approximately 1000 send attempts
73 **without** any intervening calls to *sleep()* or *usleep().*
74 The number of retry loops defaults to 1, thus a maximum of
75 1000 send attempts is performed before returning to the user
76 application. This value can be set at any point after RMR
77 initialisation using the *rmr_set_stimeout()* function
78 allowing the user application to completely disable retires
79 (set to 0), or to increase the number of retry loops.
82 Transport Level Blocking
83 ------------------------
85 The underlying transport mechanism used to send messages is
86 configured in *non-blocking* mode. This means that if a
87 message cannot be sent immediately the transport mechanism
88 will **not** pause with the assumption that the inability to
89 send will clear quickly (within a few milliseconds). This
90 means that when the retry loop is completely disabled (set to
91 0), that the failure to accept a message for sending by the
92 underlying mechanisms (software or hardware) will be reported
93 immediately to the user application.
95 It should be noted that depending on the underlying transport
96 mechanism being used, it is extremely likely that retry
97 conditions will happen during normal operations. These are
98 completely out of RMR's control, and there is nothing that
99 RMR can do to avoid or mitigate these other than by allowing
100 RMR to retry the send operation, and even then it is possible
101 (e.g., during connection reattempts), that a single retry
102 loop is not enough to guarantee a successful send.
108 On success, a new message buffer, with an empty payload, is
109 returned for the application to use for the next send. The
110 state in this buffer will reflect the overall send operation
111 state and should be ``RMR_OK.``
113 If the state in the returned buffer is anything other than
114 ``RMR_OK,`` the user application may need to attempt a
115 retransmission of the message, or take other action depending
116 on the setting of ``errno`` as described below.
118 In the event of extreme failure, a nil pointer is returned.
119 In this case the value of ``errno`` might be of some use, for
120 documentation, but there will be little that the user
121 application can do other than to move on.
127 The following values may be passed back in the *state* field
128 of the returned message buffer.
138 The wormhole ID passed in was not associated with an open
139 wormhole, or was out of range for a valid ID.
141 * - **RMR_ERR_NOWHOPEN**
143 No wormholes exist, further attempt to validate the ID are
146 * - **RMR_ERR_BADARG**
148 The message buffer pointer did not refer to a valid message.
150 * - **RMR_ERR_NOHDR**
152 The header in the message buffer was not valid or corrupted.
156 The following values may be assigned to ``errno`` on failure.
165 Parameter(s) passed to the function were not valid, or the
166 underlying message processing environment was unable to
167 interpret the message.
171 The header information in the message buffer was invalid.
175 No known endpoint for the message could be found.
179 The underlying transport refused to accept the message
180 because of a size value issue (message was not attempted to
185 The message referenced by the message buffer is corrupt (nil
186 pointer or bad internal length).
190 Internal RMR error; information provided to the message
191 transport environment was not valid.
195 Sending was not supported by the underlying message
200 The device is not in a state that can accept the message.
204 The device is not able to accept a message for sending. The
205 user application should attempt to resend.
209 The operation was interrupted by delivery of a signal before
210 the message was sent.
214 The underlying message environment timed out during the send
219 The underlying message environment is in a shutdown state.
227 The following is a simple example of how the a wormhole is
228 created (rmr_wh_open) and then how ``rmr_wh_send_msg``
229 function is used to send messages. Some error checking is
236 #include <rmr/rmr.h> // system headers omitted for clarity
239 rmr_whid_t whid = -1; // wormhole id for sending
240 void* mrc; //msg router context
242 rmr_mbuf_t* sbuf; // send buffer
244 int norm_msg_size = 1500; // most msg fit in this size
246 mrc = rmr_init( "43086", norm_msg_size, RMRFL_NONE );
248 fprintf( stderr, "[FAIL] unable to initialise RMR environment\\n" );
252 while( ! rmr_ready( mrc ) ) { // wait for routing table info
256 sbuf = rmr_alloc_msg( mrc, 2048 );
260 whid = rmr_wh_open( mrc, "localhost:6123" ); // open fails if endpoint refuses conn
261 if( RMR_WH_CONNECTED( wh ) ) {
262 snprintf( sbuf->payload, 1024, "periodic update from sender: %d", count++ );
263 sbuf->len = strlen( sbuf->payload );
264 sbuf = rmr_wh_send_msg( mrc, whid, sbuf );
277 rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
278 rmr_payload_size(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
279 rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3),
280 rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3),
281 rmr_set_stimeout(3), rmr_wh_open(3), rmr_wh_close(3),