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