blob: e347189f24a49d87ad620689aaed2af09bea5aaa [file] [log] [blame]
E. Scott Daniels117030c2020-04-10 17:17:02 -04001
2
3.. This work is licensed under a Creative Commons Attribution 4.0 International License.
4.. SPDX-License-Identifier: CC-BY-4.0
5.. CAUTION: this document is generated from source in doc/src/rtd.
6.. To make changes edit the source and recompile the document.
7.. Do NOT make changes directly to .rst or .md files.
8
9
10============================================================================================
11Man Page: rmr_send_msg
12============================================================================================
13
14RMR Library Functions
15============================================================================================
16
17
18NAME
19--------------------------------------------------------------------------------------------
20
21rmr_send_msg
22
23SYNOPSIS
24--------------------------------------------------------------------------------------------
25
26
27::
28
29 #include <rmr/rmr.h>
30 rmr_mbuf_t* rmr_send_msg( void* vctx, rmr_mbuf_t* msg );
31
32
33
34DESCRIPTION
35--------------------------------------------------------------------------------------------
36
37The rmr_send_msg function accepts a message buffer from the
38user application and attempts to send it. The destination of
39the message is selected based on the message type specified
40in the message buffer, and the matching information in the
41routing tables which are currently in use by the RMR library.
42This may actually result in the sending of the message to
43multiple destinations which could degrade expected overall
44performance of the user application. (Limiting excessive
45sending of messages is the responsibility of the
46application(s) responsible for building the routing table
47used by the RMR library, and not the responsibility of the
48library.)
49
50Retries
51~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
52
53The send operations in RMR will retry *soft* send failures
54until one of three conditions occurs:
55
56
57
581.
59
60 The message is sent without error
61
62
632.
64
65 The underlying transport reports a *hard* failure
66
67
683.
69
70 The maximum number of retry loops has been attempted
71
72
73A retry loop consists of approximately 1000 send attempts
74**without** any intervening calls to *sleep()* or *usleep().*
75The number of retry loops defaults to 1, thus a maximum of
761000 send attempts is performed before returning to the user
77application. This value can be set at any point after RMr
78initialisation using the *rmr_set_stimeout()* function
79allowing the user application to completely disable retires
80(set to 0), or to increase the number of retry loops.
81
82Transport Level Blocking
83~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
84
85The underlying transport mechanism used to send messages is
86configured in *non-blocking* mode. This means that if a
87message cannot be sent immediately the transport mechanism
88will **not** pause with the assumption that the inability to
89send will clear quickly (within a few milliseconds). This
90means that when the retry loop is completely disabled (set to
910), that the failure to accept a message for sending by the
92underlying mechanisms (software or hardware) will be reported
93immediately to the user application.
94
95It should be noted that depending on the underlying transport
96mechanism being used, it is extremely likely that retry
97conditions will happen during normal operations. These are
98completely out of RMR's control, and there is nothing that
99RMR can do to avoid or mitigate these other than by allowing
100RMR to retry the send operation, and even then it is possible
101(e.g., during connection reattempts), that a single retry
102loop is not enough to guarantee a successful send.
103
104RETURN VALUE
105--------------------------------------------------------------------------------------------
106
107On success, a new message buffer, with an empty payload, is
108returned for the application to use for the next send. The
109state in this buffer will reflect the overall send operation
110state and will be RMR_OK when the send was successful.
111
112When the message cannot be successfully sent this function
113will return the unsent (original) message buffer with the
114state set to indicate the reason for failure. The value of
115*errno* may also be set to reflect a more detailed failure
116reason if it is known.
117
118In the event of extreme failure, a nil pointer is returned.
119In this case the value of errno might be of some use, for
120documentation, but there will be little that the user
121application can do other than to move on.
122
123**CAUTION:** In some cases it is extremely likely that the
124message returned by the send function does **not** reference
125the same memory structure. Thus is important for the user
126programme to capture the new pointer for future use or to be
127passed to rmr_free(). If you are experiencing either double
128free errors or segment faults in either rmr_free() or
129rmr_send_msg(), ensure that the return value from this
130function is being captured and used.
131
132ERRORS
133--------------------------------------------------------------------------------------------
134
135The following values may be passed back in the *state* field
136of the returned message buffer.
137
138
139
140RMR_RETRY
141
142 The message could not be sent, but the underlying
143 transport mechanism indicates that the failure is
144 temporary. If the send operation is tried again it might
145 be successful.
146
147RMR_SEND_FAILED
148
149 The send operation was not successful and the underlying
150 transport mechanism indicates a permanent (hard) failure;
151 retrying the send is not possible.
152
153RMR_ERR_BADARG
154
155 The message buffer pointer did not refer to a valid
156 message.
157
158RMR_ERR_NOHDR
159
160 The header in the message buffer was not valid or
161 corrupted.
162
163RMR_ERR_NOENDPT
164
165 The message type in the message buffer did not map to a
166 known endpoint.
167
168
169The following values may be assigned to errno on failure.
170
171
172INVAL
173
174 Parameter(s) passed to the function were not valid, or the
175 underlying message processing environment was unable to
176 interpret the message.
177
178
179ENOKEY
180
181 The header information in the message buffer was invalid.
182
183
184ENXIO
185
186 No known endpoint for the message could be found.
187
188
189EMSGSIZE
190
191 The underlying transport refused to accept the message
192 because of a size value issue (message was not attempted
193 to be sent).
194
195
196EFAULT
197
198 The message referenced by the message buffer is corrupt
199 (nil pointer or bad internal length).
200
201
202EBADF
203
204 Internal RMR error; information provided to the message
205 transport environment was not valid.
206
207
208ENOTSUP
209
210 Sending was not supported by the underlying message
211 transport.
212
213
214EFSM
215
216 The device is not in a state that can accept the message.
217
218
219EAGAIN
220
221 The device is not able to accept a message for sending.
222 The user application should attempt to resend.
223
224
225EINTR
226
227 The operation was interrupted by delivery of a signal
228 before the message was sent.
229
230
231ETIMEDOUT
232
233 The underlying message environment timed out during the
234 send process.
235
236
237ETERM
238
239 The underlying message environment is in a shutdown state.
240
241
242EXAMPLE
243--------------------------------------------------------------------------------------------
244
245The following is a simple example of how the rmr_send_msg
246function is called. In this example, the send message buffer
247is saved between calls and reused eliminating alloc/free
248cycles.
249
250
251::
252
253 static rmr_mbuf_t* send_msg = NULL; // message to send; reused on each call
254 msg_t* send_pm; // payload for send
255 msg_t* pm; // our message format in the received payload
256 if( send_msg == NULL ) {
257 send_msg = rmr_alloc_msg( mr, MAX_SIZE ); // new buffer to send
258 }
259 // reference payload and fill in message type
260 pm = (msg_t*) send_msg->payload;
261 send_msg->mtype = MT_ANSWER;
262 msg->len = generate_data( pm ); // something that fills the payload in
263 msg = rmr_send_msg( mr, send_msg ); // ensure new pointer used after send
264 if( ! msg ) {
265 return ERROR;
266 } else {
267 if( msg->state != RMR_OK ) {
268 // check for RMR_ERR_RETRY, and resend if needed
269 // else return error
270 }
271 }
272 return OK;
273
274
275
276SEE ALSO
277--------------------------------------------------------------------------------------------
278
279rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
280rmr_payload_size(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
281rmr_rts_msg(3), rmr_ready(3), rmr_mk_ring(3),
282rmr_ring_free(3), rmr_torcv_rcv(3), rmr_wh_send_msg(3)