blob: c0b7bc8ad12f0f14b6bbe92e25dd2741605b76ae [file] [log] [blame]
E. Scott Daniels392168d2019-11-06 15:12:38 -05001
2.. This work is licensed under a Creative Commons Attribution 4.0 International License.
3.. SPDX-License-Identifier: CC-BY-4.0
4.. CAUTION: this document is generated from source in doc/src/rtd.
5.. To make changes edit the source and recompile the document.
6.. Do NOT make changes directly to .rst or .md files.
7
8
9RMR User's Guide
10============================================================================================
11
12The RIC Message Router (RMR) is a library which applications
13use to send and receive messages where the message routing,
14endpoint selection, is based on the message type rather than
15on traditional DNS names or IP addresses. Because the user
16documentation for RMR is a collection of UNIX manpages
E. Scott Danielsb7a4b522019-11-07 15:35:17 -050017(included in the development package, and available via the
E. Scott Daniels392168d2019-11-06 15:12:38 -050018man command when installed), there is no separate "User's
E. Scott Danielsb7a4b522019-11-07 15:35:17 -050019Guide." To provide something for the document scrapers to
E. Scott Daniels392168d2019-11-06 15:12:38 -050020find, this is a collection of the RMR manual pages formatted
21directly from their source which might be a bit ragged when
22combined into a single markup document. Read the manual pages
23:)
24
25
26
27NAME
28--------------------------------------------------------------------------------------------
29
30rmr_alloc_msg
31
32SYNOPSIS
33--------------------------------------------------------------------------------------------
34
35
36::
37
38 #include <rmr/rmr.h>
39 rmr_mbuf_t* rmr_alloc_msg( void* ctx, int size );
40
41
42
43DESCRIPTION
44--------------------------------------------------------------------------------------------
45
46The rmr_alloc_msg function is used to allocate a buffer which
47the user programme can write into and then send through the
48RMR library. The buffer is allocated such that sending it
49requires no additional copying out of the buffer. If the
50value passed in size is 0, then the default size supplied on
51the *rmr_init* call will be used. The *ctx* parameter is the
52void context pointer that was returned by the *rmr_init*
53function.
54
55The pointer to the message buffer returned is a structure
56which has some user application visible fields; the structure
57is described in rmr.h, and is illustrated below.
58
59
60::
61
62 typedef struct {
63 int state;
64 int mtype;
65 int len;
66 unsigned char* payload;
67 unsigned char* xaction;
68 uint sub_id;
69 uint tp_state;
70 } rmr_mbuf_t;
71
72
73
74
75
76state
77
78 Is the current buffer state. Following a call to
79 rmr_send_msg the state indicates whether the buffer was
80 successfully sent which determines exactly what the
81 payload points to. If the send failed, the payload
82 referenced by the buffer is the message that failed to
83 send (allowing the application to attempt a
84 retransmission). When the state is RMR_OK the buffer
85 represents an empty buffer that the application may fill
86 in in preparation to send.
87
88
89mtype
90
91 When sending a message, the application is expected to set
92 this field to the appropriate message type value (as
93 determined by the user programme). Upon send this value
94 determines how the RMR library will route the message. For
95 a buffer which has been received, this field will contain
96 the message type that was set by the sending application.
97
98
99len
100
101 The application using a buffer to send a message is
102 expected to set the length value to the actual number of
103 bytes that it placed into the message. This is likely less
104 than the total number of bytes that the message can carry.
105 For a message buffer that is passed to the application as
106 the result of a receive call, this will be the value that
107 the sending application supplied and should indicate the
108 number of bytes in the payload which are valid.
109
110
111payload
112
113 The payload is a pointer to the actual received data. The
114 user programme may read and write from/to the memory
115 referenced by the payload up until the point in time that
116 the buffer is used on a rmr_send, rmr_call or rmr_reply
117 function call. Once the buffer has been passed back to a
118 RMR library function the user programme should **NOT**
119 make use of the payload pointer.
120
121
122xaction
123
124 The *xaction* field is a pointer to a fixed sized area in
125 the message into which the user may write a transaction
126 ID. The ID is optional with the exception of when the user
127 application uses the rmr_call function to send a message
128 and wait for the reply; the underlying RMR processing
129 expects that the matching reply message will also contain
130 the same data in the *xaction* field.
131
132
133
134sub_id
135
136 This value is the subscription ID. It, in combination with
137 the message type is used by rmr to determine the target
138 endpoint when sending a message. If the application to
139 application protocol does not warrant the use of a
140 subscription ID, the RMR constant RMR_VOID_SUBID should be
141 placed in this field. When an application is forwarding or
142 returning a buffer to the sender, it is the application's
143 responsibility to set/reset this value.
144
145
146tp_state
147
148 For C applications making use of RMR, the state of a
149 transport based failure will often be available via errno.
150 However, some wrapper environments may not have direct access
151 to the C-lib errno value. RMR send and receive operations
152 will place the current value of errno into this field which
153 should make it available to wrapper functions. User
154 applications are strongly cautioned against relying on the
155 value of errno as some transport mechanisms may not set this
156 value on all calls. This value should also be ignored any
157 time the message status is RMR_OK.
158
159
160RETURN VALUE
161--------------------------------------------------------------------------------------------
162
163The function returns a pointer to a rmr_mbuf structure, or NULL
164on error.
165
166ERRORS
167--------------------------------------------------------------------------------------------
168
169
170
171ENOMEM
172
173 Unable to allocate memory.
174
175
176SEE ALSO
177--------------------------------------------------------------------------------------------
178
179rmr_tralloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
180rmr_init_trace(3), rmr_get_trace(3), rmr_get_trlen(3),
181rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
182rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3), rmr_fib(3),
183rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3),
184rmr_ring_free(3), rmr_set_trace(3)
185
186
187NAME
188--------------------------------------------------------------------------------------------
189
190rmr_bytes2meid
191
192SYNOPSIS
193--------------------------------------------------------------------------------------------
194
195
196::
197
198 #include <rmr/rmr.h>
199 int rmr_bytes2meid( rmr_mbuf_t* mbuf, unsigned char* src, int len )
200
201
202
203DESCRIPTION
204--------------------------------------------------------------------------------------------
205
206The rmr_bytes2meid function will copy up to *len* butes from
E. Scott Daniels190665f2019-12-09 09:05:22 -0500207*src* to the managed entity ID (meid) field in the message.
208The field is a fixed length, gated by the constant
E. Scott Daniels392168d2019-11-06 15:12:38 -0500209RMR_MAX_MEID and if len is larger than this value, only
210RMR_MAX_MEID bytes will actually be copied.
211
212RETURN VALUE
213--------------------------------------------------------------------------------------------
214
215On success, the actual number of bytes copied is returned, or
216-1 to indicate a hard error. If the length is less than 0, or
217not the same as length passed in, errno is set to one of the
218errors described in the *Errors* section.
219
220ERRORS
221--------------------------------------------------------------------------------------------
222
223If the returned length does not match the length passed in,
224errno will be set to one of the following constants with the
225meaning listed below.
226
227
228
229EINVAL
230
231 The message, or an internal portion of the message, was
232 corrupted or the pointer was invalid.
233
234
235EOVERFLOW
236
237 The length passed in was larger than the maximum length of
238 the field; only a portion of the source bytes were copied.
239
240
241EXAMPLE
242--------------------------------------------------------------------------------------------
243
244
245SEE ALSO
246--------------------------------------------------------------------------------------------
247
248rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_call(3),
249rmr_free_msg(3), rmr_get_rcvfd(3), rmr_get_meid(3),
250rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
251rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
252rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3),
253rmr_ring_free(3), rmr_str2meid(3), rmr_str2xact(3),
254rmr_wh_open(3), rmr_wh_send_msg(3)
255
256
257NAME
258--------------------------------------------------------------------------------------------
259
260rmr_bytes2payload
261
262SYNOPSIS
263--------------------------------------------------------------------------------------------
264
265
266::
267
268 #include <rmr/rmr.h>
269 void rmr_bytes2payload( rmr_mbuf_t* mbuf, unsigned char* src, int len )
270
271
272
273DESCRIPTION
274--------------------------------------------------------------------------------------------
275
276This is a convenience function as some wrapper languages
277might not have the ability to directly copy into the payload
E. Scott Danielsb7a4b522019-11-07 15:35:17 -0500278buffer. The bytes from *src* for the length given are copied
279to the payload. It is the caller's responsibility to ensure
280that the payload is large enough. Upon successfully copy, the
281len field in the message buffer is updated to reflect the
282number of bytes copied.
E. Scott Daniels392168d2019-11-06 15:12:38 -0500283
284There is little error checking, and no error reporting.
285
286RETURN VALUE
287--------------------------------------------------------------------------------------------
288
289None.
290
291EXAMPLE
292--------------------------------------------------------------------------------------------
293
294
295SEE ALSO
296--------------------------------------------------------------------------------------------
297
298rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_bytes2payload(3),
299rmr_call(3), rmr_free_msg(3), rmr_get_rcvfd(3),
300rmr_get_meid(3), rmr_payload_size(3), rmr_send_msg(3),
301rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
302rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
303rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
304rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3)
305
306
307NAME
308--------------------------------------------------------------------------------------------
309
310rmr_bytes2xact
311
312SYNOPSIS
313--------------------------------------------------------------------------------------------
314
315
316::
317
318 #include <rmr/rmr.h>
319 int rmr_bytes2xact( rmr_mbuf_t* mbuf, unsigned char* src, int len )
320
321
322
323DESCRIPTION
324--------------------------------------------------------------------------------------------
325
326The rmr_bytes2xact function will copy up to *len* butes from
327*src* to the transaction ID (xaction) field in the message.
328The field is a fixed length, gated by the constant
329RMR_MAX_XID and if len is larger than this value, only
330RMR_MAX_XID bytes will actually be copied.
331
332
333RETURN VALUE
334--------------------------------------------------------------------------------------------
335
336On success, the actual number of bytes copied is returned,
337or -1 to indicate a hard error. If the length is less than
3380, or not the same as length passed in, errno is set to
339one of the errors described in the *Errors* section.
340
341ERRORS
342--------------------------------------------------------------------------------------------
343
344If the returned length does not match the length passed
345in, errno will be set to one of the following constants
346with the meaning listed below.
347
348
349EINVAL
350
351 The message, or an internal portion of the message, was
352 corrupted or the pointer was invalid.
353
354
355EOVERFLOW
356
357 The length passed in was larger than the maximum length of
358 the field; only a portion of the source bytes were copied.
359
360
361EXAMPLE
362--------------------------------------------------------------------------------------------
363
364
365SEE ALSO
366--------------------------------------------------------------------------------------------
367
368rmr_alloc_msg(3), rmr_bytes2meid(3), rmr_call(3),
369rmr_free_msg(3), rmr_get_meid(3), rmr_get_rcvfd(3),
370rmr_get_xact(3), rmr_payload_size(3), rmr_send_msg(3),
371rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
372rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
373rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
374rmr_wh_open(3), rmr_wh_send_msg(3)
375
376
377NAME
378--------------------------------------------------------------------------------------------
379
380rmr_call
381
382SYNOPSIS
383--------------------------------------------------------------------------------------------
384
385
386::
387
388 #include <rmr/rmr.h>
389 extern rmr_mbuf_t* rmr_call( void* vctx, rmr_mbuf_t* msg );
390
391
392
393DESCRIPTION
394--------------------------------------------------------------------------------------------
395
396The rmr_call function sends the user application message to a
397remote endpoint, and waits for a corresponding response
398message before returning control to the user application. The
399user application supplies a completed message buffer, as it
400would for a rmr_send call, but unlike with the send, the
401buffer returned will have the response from the application
402that received the message.
403
404Messages which are received while waiting for the response
405are queued internally by RMR, and are returned to the user
406application when rmr_rcv_msg is invoked. These messages are
407returned in th order received, one per call to rmr_rcv_msg.
408
409Call Timeout
410~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
411
412The rmr_call function implements a timeout failsafe to
413prevent, in most cases, the function from blocking forever.
414The timeout period is **not** based on time (calls to clock
415are deemed too expensive for a low latency system level
416library, but instead the period is based on the number of
417received messages which are not the response. Using a
418non-time mechanism for *timeout* prevents the async queue
419from filling (which would lead to message drops) in an
420environment where there is heavy message traffic.
421
422When the threshold number of messages have been queued
423without receiving a response message, control is returned to
424the user application and a NULL pointer is returned to
425indicate that no message was received to process. Currently
426the threshold is fixed at 20 messages, though in future
427versions of the library this might be extended to be a
428parameter which the user application may set.
429
430Retries
431~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
432
433The send operations in RMr will retry *soft* send failures
434until one of three conditions occurs:
435
436
437
4381.
439
440 The message is sent without error
441
442
4432.
444
445 The underlying transport reports a * hard * failure
446
447
4483.
449
450 The maximum number of retry loops has been attempted
451
452
453A retry loop consists of approximately 1000 send attemps **
454without** any intervening calls to * sleep() * or * usleep().
455* The number of retry loops defaults to 1, thus a maximum of
4561000 send attempts is performed before returning to the user
457application. This value can be set at any point after RMr
458initialisation using the * rmr_set_stimeout() * function
459allowing the user application to completely disable retires
460(set to 0), or to increase the number of retry loops.
461
462Transport Level Blocking
463~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
464
465The underlying transport mechanism used to send messages is
466configured in *non-blocking* mode. This means that if a
467message cannot be sent immediately the transport mechanism
468will **not** pause with the assumption that the inability to
469send will clear quickly (within a few milliseconds). This
470means that when the retry loop is completely disabled (set to
4710), that the failure to accept a message for sending by the
472underlying mechanisms (software or hardware) will be reported
473immediately to the user application.
474
475It should be noted that depending on the underlying transport
476mechanism being used, it is extremly possible that during
477normal operations that retry conditions are very likely to
478happen. These are completely out of RMr's control, and there
479is nothing that RMr can do to avoid or midigate these other
480than by allowing RMr to retry the send operation, and even
481then it is possible (e.g. during connection reattempts), that
482a single retry loop is not enough to guarentee a successful
483send.
484
485RETURN VALUE
486--------------------------------------------------------------------------------------------
487
488The rmr_call function returns a pointer to a message buffer
489with the state set to reflect the overall state of call
490processing (see Errors below). In some cases a NULL pointer
491will be returned; when this is the case only *errno* will be
492available to describe the reason for failure.
493
494ERRORS
495--------------------------------------------------------------------------------------------
496
497These values are reflected in the state field of the returned
498message.
499
500
501
502RMR_OK
503
504 The call was successful and the message buffer references
505 the response message.
506
507
508RMR_ERR_CALLFAILED
509
510 The call failed and the value of *errno,* as described
511 below, should be checked for the specific reason.
512
513
514The global "variable" *errno* will be set to one of the
515following values if the overall call processing was not
516successful.
517
518
519
520ETIMEDOUT
521
522 Too many messages were queued before receiving the
523 expected response
524
525
526ENOBUFS
527
528 The queued message ring is full, messages were dropped
529
530
531EINVAL
532
533 A parameter was not valid
534
535
536EAGAIN
537
538 The underlying message system wsa interrupted or the
539 device was busy; the message was **not** sent, and user
540 application should call this function with the message
541 again.
542
543
544EXAMPLE
545--------------------------------------------------------------------------------------------
546
547The following code bit shows one way of using the rmr_call
548function, and illustrates how the transaction ID must be set.
549
550
551::
552
553 int retries_left = 5; // max retries on dev not available
554 int retry_delay = 50000; // retry delay (usec)
555 static rmr_mbuf_t* mbuf = NULL; // response msg
556 msg_t* pm; // private message (payload)
557 m// get a send buffer and reference the payload
558 mbuf = rmr_alloc_msg( mr, RMR_MAX_RCV_BYTES );
559 pm = (msg_t*) mbuf->payload;
560 p// generate an xaction ID and fill in payload with data and msg type
561 snprintf( mbuf->xaction, RMR_MAX_XID, "%s", gen_xaction() );
562 snprintf( pm->req, sizeof( pm->req ), "{ \\"req\\": \\"num users\\"}" );
563 mbuf->mtype = MT_REQ;
564
565 msg = rmr_call( mr, msg );
566 if( ! msg ) { // probably a timeout and no msg received
567 return NULL; // let errno trickle up
568 }
569 if( mbuf->state != RMR_OK ) {
570 while( retries_left-- > 0 && // loop as long as eagain
571 errno == EAGAIN &&
572 (msg = rmr_call( mr, msg )) != NULL &&
573 mbuf->state != RMR_OK ) {
574 usleep( retry_delay );
575 }
576
577 if( mbuf == NULL || mbuf->state != RMR_OK ) {
578 rmr_free_msg( mbuf ); // safe if nil
579 return NULL;
580 }
581 }
582 // do something with mbuf
583
584
585
586SEE ALSO
587--------------------------------------------------------------------------------------------
588
589rmr_alloc_msg(3), rmr_free_msg(3), rmr_init(3),
590rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
591rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
592rmr_fib(3), rmr_has_str(3), rmr_set_stimeout(3),
593rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3)
594
595
596NAME
597--------------------------------------------------------------------------------------------
598
599rmr_wh_open
600
601SYNOPSIS
602--------------------------------------------------------------------------------------------
603
604
605::
606
607 #include <rmr/rmr.h>
608 void rmr_close( void* vctx )
609
610
611
612DESCRIPTION
613--------------------------------------------------------------------------------------------
614
615The rmr_close function closes the listen socket effectively
616cutting the application off. The route table listener is also
617stopped. Calls to rmr_rcv_msg() will fail with unpredictable
618error codes, and calls to rmr_send_msg(), rmr_call(), and
619rmr_rts_msg() will have unknown results.
620
621
622SEE ALSO
623--------------------------------------------------------------------------------------------
624
625rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
626rmr_get_rcvfd(3), rmr_payload_size(3), rmr_send_msg(3),
627rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
628rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
629rmr_mk_ring(3), rmr_ring_free(3), rmr_wh_open(3),
630rmr_wh_send_msg(3)
631
632
633NAME
634--------------------------------------------------------------------------------------------
635
636rmr_free_msg
637
638SYNOPSIS
639--------------------------------------------------------------------------------------------
640
641
642::
643
644 #include <rmr/rmr.h>
645 void rmr_free_msg( rmr_mbuf_t* mbuf );
646
647
648
649DESCRIPTION
650--------------------------------------------------------------------------------------------
651
652The message buffer is returned to the pool, or the associated
653memory is released depending on the needs of the underlying
654messaging system. This allows the user application to release
655a buffer that is not going to be used. It is safe to pass a
656nil pointer to this function, and doing so does not result in
657a change to the value of errrno.
658
659After calling, the user application should **not** use any of
660the pointers (transaction ID, or payload) which were
661available.
662
663SEE ALSO
664--------------------------------------------------------------------------------------------
665
666rmr_alloc_msg(3), rmr_call(3), rmr_init(3),
667rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
668rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
669rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3),
670rmr_ring_free(3)
671
672
673NAME
674--------------------------------------------------------------------------------------------
675
676rmr_get_meid
677
678SYNOPSIS
679--------------------------------------------------------------------------------------------
680
681
682::
683
684 #include <rmr/rmr.h>
685 char* rmr_get_meid( rmr_mbuf_t* mbuf, unsigned char* dest )
686
687
688
689DESCRIPTION
690--------------------------------------------------------------------------------------------
691
E. Scott Daniels190665f2019-12-09 09:05:22 -0500692The rmr_get_meid function will copy the managed entity ID
E. Scott Daniels392168d2019-11-06 15:12:38 -0500693(meid) field from the message into the *dest* buffer provided
E. Scott Danielsb7a4b522019-11-07 15:35:17 -0500694by the user. The buffer referenced by *dest* is assumed to be
695at least RMR_MAX_MEID bytes in length. If *dest* is NULL,
696then a buffer is allocated (the calling application is
E. Scott Daniels392168d2019-11-06 15:12:38 -0500697expected to free when the buffer is no longer needed).
698
699RETURN VALUE
700--------------------------------------------------------------------------------------------
701
702On success, a pointer to the extracted string is returned. If
E. Scott Danielsb7a4b522019-11-07 15:35:17 -0500703*dest* was supplied, then this is just a pointer to the
704caller's buffer. If *dest* was NULL, this is a pointer to the
705allocated buffer. If an error occurs, a nil pointer is
E. Scott Daniels392168d2019-11-06 15:12:38 -0500706returned and errno is set as described below.
707
708ERRORS
709--------------------------------------------------------------------------------------------
710
711If an error occurs, the value of the global variable errno
712will be set to one of the following with the indicated
713meaning.
714
715
716
717EINVAL
718
719 The message, or an internal portion of the message, was
720 corrupted or the pointer was invalid.
721
722
723ENOMEM
724
E. Scott Danielsb7a4b522019-11-07 15:35:17 -0500725 A nil pointer was passed for *dest,* however it was not
E. Scott Daniels392168d2019-11-06 15:12:38 -0500726 possible to allocate a buffer using malloc().
727
728
729SEE ALSO
730--------------------------------------------------------------------------------------------
731
732rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_bytes2meid(3),
733rmr_call(3), rmr_free_msg(3), rmr_get_rcvfd(3),
734rmr_get_xact(3), rmr_payload_size(3), rmr_send_msg(3),
735rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
736rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
737rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
738rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3)
739
740
741NAME
742--------------------------------------------------------------------------------------------
743
744rmr_get_rcvfd
745
746SYNOPSIS
747--------------------------------------------------------------------------------------------
748
749
750::
751
752 #include <rmr/rmr.h>
753 void* rmr_get_rcvfd( void* ctx )
754
755
756
757DESCRIPTION
758--------------------------------------------------------------------------------------------
759
760The rmr_get_rcvfd function returns a file descriptor which
761may be given to epoll_wait() by an application that wishes to
762use event poll in a single thread rather than block on the
763arrival of a message via calls to rmr_rcv_msg(). When
764epoll_wait() indicates that this file descriptor is ready, a
765call to rmr_rcv_msg() will not block as at least one message
766has been received.
767
768The context (ctx) pointer passed in is the pointer returned
769by the call to rmr_init().
770
771**NOTE:** There is no support for epoll in Nanomsg, thus his
772function is only supported when linking with the NNG version
773of RMr and the file descriptor returned when using the
774Nanomsg verfsion will always return an error.
775
776RETURN VALUE
777--------------------------------------------------------------------------------------------
778
779The rmr_get_rcvfd function returns a file descriptor greater
780or equal to 0 on success and -1 on error. If this function is
781called from a user application linked against the Nanomsg RMr
782library, calls will always return -1 with errno set to
783EINVAL.
784
785ERRORS
786--------------------------------------------------------------------------------------------
787
788The following error values are specifically set by this RMR
789function. In some cases the error message of a system call is
790propagated up, and thus this list might be incomplete.
791
792
793EINVAL
794
795 The use of this function is invalid in this environment.
796
797
798EXAMPLE
799--------------------------------------------------------------------------------------------
800
801The following short code bit illustrates the use of this
802function. Error checking has been omitted for clarity.
803
804
805::
806
807 #include <stdio.h>
808 #include <stdlib.h>
809 #include <sys/epoll.h>
810 #include <rmr/rmr.h>
811 int main() {
812 int rcv_fd; // pollable fd
813 void* mrc; //msg router context
814 struct epoll_event events[10]; // support 10 events to poll
815 struct epoll_event epe; // event definition for event to listen to
816 int ep_fd = -1;
817 rmr_mbuf_t* msg = NULL;
818 int nready;
819 int i;
820
821 mrc = rmr_init( "43086", RMR_MAX_RCV_BYTES, RMRFL_NONE );
822 rcv_fd = rmr_get_rcvfd( mrc );
823
824 rep_fd = epoll_create1( 0 ); _ B ,// initialise epoll environment
825 epe.events = EPOLLIN;
826 epe.data.fd = rcv_fd;
827 epoll_ctl( ep_fd, EPOLL_CTL_ADD, rcv_fd, &epe ); // add our info to the mix
828
829 while( 1 ) {
830 nready = epoll_wait( ep_fd, events, 10, -1 ); // -1 == block forever (no timeout)
831 for( i = 0; i < nready && i < 10; i++ ) { // loop through to find what is ready
832 if( events[i].data.fd == rcv_fd ) { // RMr has something
833 msg = rmr_rcv_msg( mrc, msg );
834 if( msg ) {
835 // do something with msg
836 }
837 }
838
839 // check for other ready fds....
840 }
841 }
842 }
843
844
845
846SEE ALSO
847--------------------------------------------------------------------------------------------
848
849rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
850rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
851rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
852rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3),
853rmr_ring_free(3)
854
855
856NAME
857--------------------------------------------------------------------------------------------
858
859rmr_get_src
860
861SYNOPSIS
862--------------------------------------------------------------------------------------------
863
864
865::
866
867 #include <rmr/rmr.h>
868 unsigned char* rmr_get_src( rmr_mbuf_t* mbuf, unsigned char* dest )
869
870
871
872DESCRIPTION
873--------------------------------------------------------------------------------------------
874
875The rmr_get_src function will copy the *source* information
876from the message to a buffer (dest) supplied by the user. In
877an RMr message, the source is the sender's information that
878is used for return to sender function calls, and is generally
879the hostname and port in the form *name*. The source might be
880an IP address port combination; the data is populated by the
881sending process and the only requirement is that it be
882capable of being used to start a TCP session with the sender.
883
884The maximum size allowed by RMr is 64 bytes (including the
885nil string terminator), so the user must ensure that the
886destination buffer given is at least 64 bytes.
887
888RETURN VALUE
889--------------------------------------------------------------------------------------------
890
891On success, a pointer to the destination buffer is given as a
892convenience to the user programme. On failure, a nil pointer
893is returned and the value of errno is set.
894
895ERRORS
896--------------------------------------------------------------------------------------------
897
898If an error occurs, the value of the global variable errno
899will be set to one of the following with the indicated
900meaning.
901
902
903
904EINVAL
905
906 The message, or an internal portion of the message, was
907 corrupted or the pointer was invalid.
908
909
910SEE ALSO
911--------------------------------------------------------------------------------------------
912
913rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_bytes2meid(3),
914rmr_call(3), rmr_free_msg(3), rmr_get_rcvfd(3),
915rmr_get_srcip(3), rmr_payload_size(3), rmr_send_msg(3),
916rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
917rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
918rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
919rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3)
920
921
922NAME
923--------------------------------------------------------------------------------------------
924
925rmr_get_srcip
926
927SYNOPSIS
928--------------------------------------------------------------------------------------------
929
930
931::
932
933 #include <rmr/rmr.h>
934 unsigned char* rmr_get_srcip( rmr_mbuf_t* mbuf, unsigned char* dest )
935
936
937
938DESCRIPTION
939--------------------------------------------------------------------------------------------
940
941The rmr_get_srcip function will copy the *source IP address*
942from the message to a buffer (dest) supplied by the user. In
943an RMr message, the source IP address is the sender's
944information that is used for return to sender function calls;
945this function makes it available to the user application. The
946address is maintained as IP:port where *IP* could be either
947an IPv6 or IPv4 address depending on what was provided by the
948sending application.
949
950The maximum size allowed by RMr is 64 bytes (including the
951nil string terminator), so the user must ensure that the
952destination buffer given is at least 64 bytes. The user
953application should use the RMr constant RMR_MAX_SRC to ensure
954that the buffer supplied is large enough, and to protect
955against future RMr enhancements which might increase the
956address buffer size requirement.
957
958RETURN VALUE
959--------------------------------------------------------------------------------------------
960
961On success, a pointer to the destination buffer is given as a
962convenience to the user programme. On failure, a nil pointer
963is returned and the value of errno is set.
964
965ERRORS
966--------------------------------------------------------------------------------------------
967
968If an error occurs, the value of the global variable errno
969will be set to one of the following with the indicated
970meaning.
971
972
973
974EINVAL
975
976 The message, or an internal portion of the message, was
977 corrupted or the pointer was invalid.
978
979
980SEE ALSO
981--------------------------------------------------------------------------------------------
982
983rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_bytes2meid(3),
984rmr_call(3), rmr_free_msg(3), rmr_get_rcvfd(3),
985rmr_get_src(3), rmr_payload_size(3), rmr_send_msg(3),
986rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
987rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
988rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
989rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3)
990
991
992NAME
993--------------------------------------------------------------------------------------------
994
995rmr_get_trace
996
997SYNOPSIS
998--------------------------------------------------------------------------------------------
999
1000
1001::
1002
1003 #include <rmr/rmr.h>
1004 int rmr_get_trace( rmr_mbuf_t* mbuf, unsigned char* dest, int size )
1005
1006
1007
1008DESCRIPTION
1009--------------------------------------------------------------------------------------------
1010
1011The rmr_get_trace function will copy the trace information
1012from the message into the user's allocated memory referenced
1013by dest. The size parameter is assumed to be the maximum
1014number of bytes which can be copied (size of the destination
1015buffer).
1016
1017RETURN VALUE
1018--------------------------------------------------------------------------------------------
1019
1020On success, the number of bytes actually copied is returned.
1021If the return value is 0, no bytes copied, then the reason
1022could be that the message pointer was nil, or the size
1023parameter was <= 0.
1024
1025SEE ALSO
1026--------------------------------------------------------------------------------------------
1027
1028rmr_alloc_msg(3), rmr_tralloc_msg(3), rmr_bytes2xact(3),
1029rmr_bytes2meid(3), rmr_call(3), rmr_free_msg(3),
1030rmr_get_rcvfd(3), rmr_get_trlen(3), rmr_init(3),
1031rmr_init_trace(3), rmr_payload_size(3), rmr_send_msg(3),
1032rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
1033rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
1034rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
1035rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3),
1036rmr_set_trace(3), rmr_trace_ref(3)
1037
1038
1039NAME
1040--------------------------------------------------------------------------------------------
1041
1042rmr_get_trlen
1043
1044SYNOPSIS
1045--------------------------------------------------------------------------------------------
1046
1047
1048::
1049
1050 #include <rmr/rmr.h>
1051 int rmr_get_trlen( rmr_mbuf_t* msg );
1052
1053
1054
1055DESCRIPTION
1056--------------------------------------------------------------------------------------------
1057
1058Given a message buffer, this function returns the amount of
1059space (bytes) that have been allocated for trace data. If no
1060trace data has been allocated, then 0 is returned.
1061
1062RETURN VALUE
1063--------------------------------------------------------------------------------------------
1064
1065The number of bytes allocated for trace information in the
1066given message.
1067
1068ERRORS
1069--------------------------------------------------------------------------------------------
1070
1071
1072
1073INVAL
1074
1075 Parameter(s) passed to the function were not valid.
1076
1077
1078SEE ALSO
1079--------------------------------------------------------------------------------------------
1080
1081rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
1082rmr_get_trace(3), rmr_init(3), rmr_init_trace(3),
1083rmr_send_msg(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
1084rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3),
1085rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3),
1086rmr_set_trace(3), rmr_tralloc_msg(3)
1087
1088
1089NAME
1090--------------------------------------------------------------------------------------------
1091
1092rmr_get_xact
1093
1094SYNOPSIS
1095--------------------------------------------------------------------------------------------
1096
1097
1098::
1099
1100 #include <rmr/rmr.h>
1101 char* rmr_get_xact( rmr_mbuf_t* mbuf, unsigned char* dest )
1102
1103
1104
1105DESCRIPTION
1106--------------------------------------------------------------------------------------------
1107
1108The rmr_get_xact function will copy the transaction field
1109from the message into the *dest* buffer provided by the user.
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05001110The buffer referenced by *dest* is assumed to be at least
1111RMR_MAX_XID bytes in length. If *dest* is NULL, then a buffer
1112is allocated (the calling application is expected to free
1113when the buffer is no longer needed).
E. Scott Daniels392168d2019-11-06 15:12:38 -05001114
1115RETURN VALUE
1116--------------------------------------------------------------------------------------------
1117
1118On success, a pointer to the extracted string is returned. If
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05001119*dest* was supplied, then this is just a pointer to the
1120caller's buffer. If *dest* was NULL, this is a pointer to the
1121allocated buffer. If an error occurs, a nil pointer is
E. Scott Daniels392168d2019-11-06 15:12:38 -05001122returned and errno is set as described below.
1123
1124ERRORS
1125--------------------------------------------------------------------------------------------
1126
1127If an error occurs, the value of the global variable errno
1128will be set to one of the following with the indicated
1129meaning.
1130
1131
1132
1133EINVAL
1134
1135 The message, or an internal portion of the message, was
1136 corrupted or the pointer was invalid.
1137
1138
1139ENOMEM
1140
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05001141 A nil pointer was passed for *dest,* however it was not
E. Scott Daniels392168d2019-11-06 15:12:38 -05001142 possible to allocate a buffer using malloc().
1143
1144
1145SEE ALSO
1146--------------------------------------------------------------------------------------------
1147
1148rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_bytes2meid(3),
1149rmr_call(3), rmr_free_msg(3), rmr_get_rcvfd(3),
1150rmr_get_meid(3), rmr_payload_size(3), rmr_send_msg(3),
1151rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
1152rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
1153rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
1154rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3)
1155
1156
1157NAME
1158--------------------------------------------------------------------------------------------
1159
1160rmr_init
1161
1162SYNOPSIS
1163--------------------------------------------------------------------------------------------
1164
1165
1166::
1167
1168 #include <rmr/rmr.h>
1169 void* rmr_init( char* proto_port, int max_msg_size, int flags );
1170
1171
1172
1173DESCRIPTION
1174--------------------------------------------------------------------------------------------
1175
1176The rmr_init function prepares the environment for sending
1177and receiving messages. It does so by establishing a worker
1178thread (pthread) which subscribes to a route table generator
1179which provides the necessary routing information for the RMR
1180library to send messages.
1181
1182*Port* is used to listen for connection requests from other
E. Scott Danielsa1575da2020-01-24 16:00:11 -05001183RMR based applications. The *max_msg_size* parameter is used
1184to allocate receive buffers and is the maximum message size
1185which the application expects to receive. This value is the
1186sum of **both** the maximum payload size **and** the maximum
1187trace data size. This value is also used as the default
1188message size when allocating message buffers. Messages
1189arriving which are longer than the given maximum will be
1190dropped without notification to the application. A warning is
1191written to standard error for the first message which is too
1192large on each connection.
E. Scott Daniels392168d2019-11-06 15:12:38 -05001193
1194*Flags* allows for selection of some RMr options at the time
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05001195of initialisation. These are set by ORing RMRFL constants
E. Scott Daniels392168d2019-11-06 15:12:38 -05001196from the RMr header file. Currently the following flags are
1197supported:
1198
1199
1200
1201RMRFL_NONE
1202
1203 No flags are set.
1204
1205
1206RMRFL_NOTHREAD
1207
1208 The route table collector thread is not to be started.
1209 This should only be used by the route table generator
1210 application if it is based on RMr.
1211
1212
1213RMRFL_MTCALL
1214
1215 Enable multi-threaded call support.
E. Scott Danielsa1575da2020-01-24 16:00:11 -05001216
1217 &ditem Some underlying transport providers (e.g. SI95)
1218 enable locking to be turned off if the user application is
1219 single threaded, or otherwise can guarantee that RMR
1220 functions will not be invoked concurrently from different
1221 threads. Turning off locking can help make message receipt
1222 more efficient. If this flag is set when the underlying
1223 transport does not support disabling locks, it will be
1224 ignored.
E. Scott Daniels392168d2019-11-06 15:12:38 -05001225
1226
1227Multi-threaded Calling
1228~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1229
1230The support for an application to issue a *blocking call* by
1231the rmr_call() function was limited such that only user
1232applications which were operating in a single thread could
1233safely use the function. Further, timeouts were message count
1234based and not time unit based. Multi-threaded call support
1235adds the ability for a user application with multiple threads
E. Scott Danielsa1575da2020-01-24 16:00:11 -05001236to invoke a blocking call function with the guarantee that
E. Scott Daniels392168d2019-11-06 15:12:38 -05001237the correct response message is delivered to the thread. The
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05001238additional support is implemented with the *rmr_mt_call()*
1239and *rmr_mt_rcv()* function calls.
E. Scott Daniels392168d2019-11-06 15:12:38 -05001240
1241Multi-threaded call support requires the user application to
1242specifically enable it when RMr is initialised. This is
1243necessary because a second, dedicated, receiver thread must
1244be started, and requires all messages to be examined and
1245queued by this thread. The additional overhead is minimal,
1246queuing information is all in the RMr message header, but as
1247an additional process is necessary the user application must
1248"opt in" to this approach.
1249
1250
1251ENVIRONMENT
1252--------------------------------------------------------------------------------------------
1253
1254As a part of the initialisation process rmr_init will look
1255into the available environment variables to influence it's
1256setup. The following variables will be used when found.
1257
1258
1259
1260RMR_SEED_RT
1261
1262 Assumes this is the filename of the seed route table file
1263 to use. In normal situations, the library will wait for an
1264 update from the route table generator (expected within a
1265 few seconds of initialisation) before being able to send
1266 messages. However, in some situations where a bootstrap
1267 table is necessary, this is the means to supply it to the
1268 library.
1269
1270
1271RMR_RTG_SVC
1272
1273 The route table generator assumes that RMr is listening on
1274 a well known port (4561) by default, but this environment
1275 variable can be used to change the listening port if
1276 needed. The value of the variable is expected to be just
1277 the port.
1278
1279
1280RETURN VALUE
1281--------------------------------------------------------------------------------------------
1282
1283The rmr_init function returns a void pointer (a contex if you
1284will) that is passed as the first parameter to nearly all
1285other RMR functions. If rmr_init is unable to properly
1286initialise the environment, NULL is returned and errno is set
1287to an appropriate value.
1288
1289ERRORS
1290--------------------------------------------------------------------------------------------
1291
1292The following error values are specifically set by this RMR
1293function. In some cases the error message of a system call is
1294propagated up, and thus this list might be incomplete.
1295
1296
1297ENOMEM
1298
1299 Unable to allocate memory.
1300
1301
1302EXAMPLE
1303--------------------------------------------------------------------------------------------
1304
1305
1306::
1307
1308 void* uh;
1309 rmr_mbuf* buf = NULL;
1310 uh = rmr_init( "43086", 4096, 0 );
1311 buf = rmr_rcv_msg( uh, buf );
1312
1313
1314
1315SEE ALSO
1316--------------------------------------------------------------------------------------------
1317
1318rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
1319rmr_get_rcvfd(3), rmr_mt_call(3), rmr_mt_rcv(3),
1320rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
1321rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
1322rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3),
1323rmr_ring_free(3)
1324
1325
1326NAME
1327--------------------------------------------------------------------------------------------
1328
1329rmr_init_trace
1330
1331SYNOPSIS
1332--------------------------------------------------------------------------------------------
1333
1334
1335::
1336
1337 #include <rmr/rmr.h>
1338 void* rmr_init_trace( void* ctx )
1339
1340
1341
1342DESCRIPTION
1343--------------------------------------------------------------------------------------------
1344
1345The rmr_init_trace function establishes the default trace
1346space placed in each message buffer allocated with
1347rmr_alloc_msg(). If this function is never called, then no
1348trace space is allocated by default into any message buffer.
1349
1350Trace space allows the user application to pass some trace
1351token, or other data with the message, but outside of the
1352payload. Trace data may be added to any message with
1353rmr_set_trace(), and may be extracted from a message with
1354rmr_get_trace(). The number of bytes that a message contains
1355for/with trace data can be determined by invoking
1356rmr_get_trlen().
1357
1358This function may be safely called at any time during the
1359life of the user programme to (re)set the default trace space
1360reserved. If the user programme needs to allocate a message
1361with trace space of a different size than is allocated by
1362default, without fear of extra overhead of reallocating a
1363message later, the rmr_tralloc_msg() function can be used.
1364
1365RETURN VALUE
1366--------------------------------------------------------------------------------------------
1367
1368A value of 1 is returned on success, and 0 on failure. A
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05001369failure indicates that the RMr context (a void pointer passed
1370to this function was not valid.
E. Scott Daniels392168d2019-11-06 15:12:38 -05001371
1372SEE ALSO
1373--------------------------------------------------------------------------------------------
1374
1375rmr_alloc_msg(3), rmr_tr_alloc_msg(3), rmr_call(3),
1376rmr_free_msg(3), rmr_get_rcvfd(3), rmr_get_trace(3),
1377rmr_get_trlen(3), rmr_payload_size(3), rmr_send_msg(3),
1378rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
1379rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
1380rmr_mk_ring(3), rmr_ring_free(3), rmr_set_trace(3)
1381
1382
1383NAME
1384--------------------------------------------------------------------------------------------
1385
1386rmr_mt_call
1387
1388SYNOPSIS
1389--------------------------------------------------------------------------------------------
1390
1391
1392::
1393
1394 #include <rmr/rmr.h>
1395 extern rmr_mbuf_t* rmr_mt_call( void* vctx, rmr_mbuf_t* msg, int id, int timeout );
1396
1397
1398
1399DESCRIPTION
1400--------------------------------------------------------------------------------------------
1401
1402The rmr_mt_call function sends the user application message
1403to a remote endpoint, and waits for a corresponding response
1404message before returning control to the user application. The
1405user application supplies a completed message buffer, as it
1406would for a rmr_send_msg call, but unlike with a send, the
1407buffer returned will have the response from the application
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05001408that received the message. The thread invoking the
1409*rmr_mt_call()* will block until a message arrives or until
E. Scott Daniels392168d2019-11-06 15:12:38 -05001410*timeout* milliseconds has passed; which ever comes first.
1411Using a timeout value of zero (0) will cause the thread to
1412block without a timeout.
1413
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05001414The *id* supplied as the third parameter is an integer in the
1415range of 2 through 255 inclusive. This is a caller defined
1416"thread number" and is used to match the response message
1417with the correct user application thread. If the ID value is
1418not in the proper range, the attempt to make the call will
1419fail.
E. Scott Daniels392168d2019-11-06 15:12:38 -05001420
1421Messages which are received while waiting for the response
1422are queued on a *normal* receive queue and will be delivered
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05001423to the user application with the next invocation of
1424*rmr_mt_rcv()* or *rmr_rvv_msg().* by RMR, and are returned
E. Scott Daniels392168d2019-11-06 15:12:38 -05001425to the user application when rmr_rcv_msg is invoked. These
1426messages are returned in th order received, one per call to
1427rmr_rcv_msg.
1428
1429NOTE: Currently the multi-threaded functions are supported
1430only when the NNG transport mechanism is being used. It will
1431not be possible to link a programme using the Nanomsg version
1432of the library when references to this function are present.
1433
1434The Transaction ID
1435~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1436
1437The user application is responsible for setting the value of
1438the transaction ID field before invoking *rmr_mt_call.* The
1439transaction ID is a RMR_MAX_XID byte field that is used to
1440match the response message when it arrives. RMr will compare
1441**all** of the bytes in the field, so the caller must ensure
1442that they are set correctly to avoid missing the response
1443message. (The application which returns the response message
1444is also expected to ensure that the return buffer has the
1445matching transaction ID. This can be done transparently if
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05001446the application uses the *rmr_rts_msg()* function and does
E. Scott Daniels392168d2019-11-06 15:12:38 -05001447not adjust the transaction ID.
1448
1449Retries
1450~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1451
1452The send operations in RMr will retry *soft* send failures
1453until one of three conditions occurs:
1454
1455
1456
14571.
1458
1459 The message is sent without error
1460
1461
14622.
1463
1464 The underlying transport reports a * hard * failure
1465
1466
14673.
1468
1469 The maximum number of retry loops has been attempted
1470
1471
1472A retry loop consists of approximately 1000 send attemps **
1473without** any intervening calls to * sleep() * or * usleep().
1474* The number of retry loops defaults to 1, thus a maximum of
14751000 send attempts is performed before returning to the user
1476application. This value can be set at any point after RMr
1477initialisation using the * rmr_set_stimeout() * function
1478allowing the user application to completely disable retires
1479(set to 0), or to increase the number of retry loops.
1480
1481Transport Level Blocking
1482~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1483
1484The underlying transport mechanism used to send messages is
1485configured in *non-blocking* mode. This means that if a
1486message cannot be sent immediately the transport mechanism
1487will **not** pause with the assumption that the inability to
1488send will clear quickly (within a few milliseconds). This
1489means that when the retry loop is completely disabled (set to
14900), that the failure to accept a message for sending by the
1491underlying mechanisms (software or hardware) will be reported
1492immediately to the user application.
1493
1494It should be noted that depending on the underlying transport
1495mechanism being used, it is extremly possible that during
1496normal operations that retry conditions are very likely to
1497happen. These are completely out of RMr's control, and there
1498is nothing that RMr can do to avoid or midigate these other
1499than by allowing RMr to retry the send operation, and even
1500then it is possible (e.g. during connection reattempts), that
1501a single retry loop is not enough to guarentee a successful
1502send.
1503
1504RETURN VALUE
1505--------------------------------------------------------------------------------------------
1506
1507The rmr_mt_call function returns a pointer to a message
1508buffer with the state set to reflect the overall state of
1509call processing. If the state is RMR_OK then the buffer
1510contains the response message; otherwise the state indicates
1511the error encountered while attempting to send the message.
1512
1513If no response message is received when the timeout period
1514has expired, a nil pointer will be returned (NULL).
1515
1516ERRORS
1517--------------------------------------------------------------------------------------------
1518
1519These values are reflected in the state field of the returned
1520message.
1521
1522
1523
1524RMR_OK
1525
1526 The call was successful and the message buffer references
1527 the response message.
1528
1529
1530RMR_ERR_BADARG
1531
1532 An argument passed to the function was invalid.
1533
1534
1535RMR_ERR_CALLFAILED
1536
1537 The call failed and the value of *errno,* as described
1538 below, should be checked for the specific reason.
1539
1540
1541RMR_ERR_NOENDPT
1542
1543 An endpoint associated with the message type could not be
1544 found in the route table.
1545
1546
1547RMR_ERR_RETRY
1548
1549 The underlying transport mechanism was unable to accept
1550 the message for sending. The user application can retry
1551 the call operation if appropriate to do so.
1552
1553
1554The global "variable" *errno* will be set to one of the
1555following values if the overall call processing was not
1556successful.
1557
1558
1559
1560ETIMEDOUT
1561
1562 Too many messages were queued before receiving the
1563 expected response
1564
1565
1566ENOBUFS
1567
1568 The queued message ring is full, messages were dropped
1569
1570
1571EINVAL
1572
1573 A parameter was not valid
1574
1575
1576EAGAIN
1577
1578 The underlying message system wsa interrupted or the
1579 device was busy; the message was **not** sent, and user
1580 application should call this function with the message
1581 again.
1582
1583
1584EXAMPLE
1585--------------------------------------------------------------------------------------------
1586
1587The following code bit shows one way of using the rmr_mt_call
1588function, and illustrates how the transaction ID must be set.
1589
1590
1591::
1592
1593 int retries_left = 5; // max retries on dev not available
1594 static rmr_mbuf_t* mbuf = NULL; // response msg
1595 msg_t* pm; // private message (payload)
1596 m// get a send buffer and reference the payload
1597 mbuf = rmr_alloc_msg( mr, RMR_MAX_RCV_BYTES );
1598 pm = (msg_t*) mbuf->payload;
1599 p// generate an xaction ID and fill in payload with data and msg type
1600 rmr_bytes2xact( mbuf, xid, RMR_MAX_XID );
1601 snprintf( pm->req, sizeof( pm->req ), "{ \\"req\\": \\"num users\\"}" );
1602 mbuf->mtype = MT_USR_RESP;
1603
1604 msg = rmr_mt_call( mr, msg, my_id, 100 ); e :// wait up to 100ms
1605 if( ! msg ) { // probably a timeout and no msg received
1606 return NULL; // let errno trickle up
1607 }
1608 if( mbuf->state != RMR_OK ) {
1609 while( retries_left-- > 0 && // loop as long as eagain
1610 mbuf->state == RMR_ERR_RETRY &&
1611 (msg = rmr_mt_call( mr, msg )) != NULL &&
1612 mbuf->state != RMR_OK ) {
1613 usleep( retry_delay );
1614 }
1615
1616 if( mbuf == NULL || mbuf->state != RMR_OK ) {
1617 rmr_free_msg( mbuf ); // safe if nil
1618 return NULL;
1619 }
1620 }
1621 // do something with mbuf
1622
1623
1624
1625SEE ALSO
1626--------------------------------------------------------------------------------------------
1627
1628rmr_alloc_msg(3), rmr_free_msg(3), rmr_init(3),
1629rmr_mt_rcv(3), rmr_payload_size(3), rmr_send_msg(3),
1630rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
1631rmr_ready(3), rmr_fib(3), rmr_has_str(3),
1632rmr_set_stimeout(3), rmr_tokenise(3), rmr_mk_ring(3),
1633rmr_ring_free(3)
1634
1635
1636NAME
1637--------------------------------------------------------------------------------------------
1638
1639rmr_mt_rcv
1640
1641SYNOPSIS
1642--------------------------------------------------------------------------------------------
1643
1644
1645::
1646
1647 #include <rmr/rmr.h>
1648 rmr_mbuf_t* rmr_mt_rcv( void* vctx, rmr_mbuf_t* old_msg, int timeout );
1649
1650
1651
1652DESCRIPTION
1653--------------------------------------------------------------------------------------------
1654
1655The rmr_mt_rcv function blocks until a message is received,
1656or the timeout period (milliseconds) has passed. The result
1657is an RMr message buffer which references a received message.
1658In the case of a timeout the state will be reflected in an
1659"empty buffer" (if old_msg was not nil, or simply with the
1660return of a nil pointer. If a timeout value of zero (0) is
1661given, then the function will block until the next message
1662received.
1663
1664The *vctx* pointer is the pointer returned by the rmr_init
1665function. *Old_msg* is a pointer to a previously used message
1666buffer or NULL. The ability to reuse message buffers helps to
1667avoid alloc/free cycles in the user application. When no
1668buffer is available to supply, the receive function will
1669allocate one.
1670
1671The *old_msg* parameter allows the user to pass a previously
1672generated RMr message back to RMr for reuse. Optionally, the
1673user application may pass a nil pointer if no reusable
1674message is available. When a timeout occurs, and old_msg was
1675not nil, the state will be returned by returning a pointer to
1676the old message with the state set.
1677
1678It is possible to use the *rmr_rcv_msg()* function instead of
1679this function. Doing so might be advantagous if the user
1680programme does not always start the multi-threaded mode and
1681the use of *rmr_rcv_msg()* would make the flow of the code
1682more simple. The advantags of using this function are the
1683ability to set a timeout without using epoll, and a small
1684performance gain (if multi-threaded mode is enabled, and the
1685*rmr_rcv_msg()* function is used, it simply invokes this
1686function without a timeout value, thus there is the small
1687cost of a second call that results). Similarly, the
1688*rmr_torcv_msg()* call can be used when in multi-threaded
1689mode with the same "pass through" overhead to using this
1690function directly.
1691
1692NOTE: Currently the multi-threaded functions are supported
1693only when the NNG transport mechanism is being used. It will
1694not be possible to link a programme using the nanomsg version
1695of the library when references to this function are present.
1696
1697RETURN VALUE
1698--------------------------------------------------------------------------------------------
1699
1700When a message is received before the timeout period expires,
1701a pointer to the RMr message buffer which describes the
1702message is returned. This will, with a high probability, be a
1703different message buffer than *old_msg;* the user application
1704should not continue to use *old_msg* after it is passed to
1705this function.
1706
1707In the event of a timeout the return value will be the old
1708msg with the state set, or a nil pointer if no old message
1709was provided.
1710
1711ERRORS
1712--------------------------------------------------------------------------------------------
1713
1714The *state* field in the message buffer will be set to one of
1715the following values:
1716
1717
1718
1719RMR_OK
1720
1721 The message was received without error.
1722
1723
1724RMR_ERR_BADARG
1725
1726 A parameter passed to the function was not valid (e.g. a
1727 nil pointer). indicate either RMR_OK or RMR_ERR_EMPTY if
1728 an empty message was received.
1729
1730
1731RMR_ERR_EMPTY
1732
1733 The message received had no associated data. The length of
1734 the message will be 0.
1735
1736
1737RMR_ERR_NOTSUPP
1738
1739 The multi-threaded option was not enabled when RMr was
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05001740 initialised. See the man page for *rmr_init()* for
E. Scott Daniels392168d2019-11-06 15:12:38 -05001741 details.
1742
1743
1744RMR_ERR_RCVFAILED
1745
1746 A hard error occurred preventing the receive from
1747 completing.
1748
1749When a nil pointer is returned, or any other state value was
1750set in the message buffer, errno will be set to one of the
1751following:
1752
1753
1754
1755INVAL
1756
1757 Parameter(s) passed to the function were not valid.
1758
1759
1760EBADF
1761
1762 The underlying message transport is unable to process the
1763 request.
1764
1765
1766ENOTSUP
1767
1768 The underlying message transport is unable to process the
1769 request.
1770
1771
1772EFSM
1773
1774 The underlying message transport is unable to process the
1775 request.
1776
1777
1778EAGAIN
1779
1780 The underlying message transport is unable to process the
1781 request.
1782
1783
1784EINTR
1785
1786 The underlying message transport is unable to process the
1787 request.
1788
1789
1790ETIMEDOUT
1791
1792 The underlying message transport is unable to process the
1793 request.
1794
1795
1796ETERM
1797
1798 The underlying message transport is unable to process the
1799 request.
1800
1801
1802EXAMPLE
1803--------------------------------------------------------------------------------------------
1804
1805
1806
1807::
1808
1809 rmr_mbuf_t* mbuf = NULL; // received msg
1810 msg = rmr_mt_recv( mr, mbuf, 100 ); // wait up to 100ms
1811 if( msg != NULL ) {
1812 switch( msg->state ) {
1813 case RMR_OK:
1814 printf( "got a good message\\n" );
1815 break;
1816 case RMR_ERR_EMPTY:
1817 printf( "received timed out\\n" );
1818 break;
1819 default:
1820 printf( "receive error: %d\\n", mbuf->state );
1821 break;
1822 }
1823 } else {
1824 printf( "receive timeout (nil)\\n" );
1825 }
1826
1827
1828
1829SEE ALSO
1830--------------------------------------------------------------------------------------------
1831
1832rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
1833rmr_get_rcvfd(3), rmr_init(3), rmr_mk_ring(3),
1834rmr_mt_call(3), rmr_payload_size(3), rmr_send_msg(3),
1835rmr_torcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
1836rmr_ready(3), rmr_ring_free(3), rmr_torcv_msg(3)
1837
1838
1839NAME
1840--------------------------------------------------------------------------------------------
1841
1842rmr_payload_size
1843
1844SYNOPSIS
1845--------------------------------------------------------------------------------------------
1846
1847
1848::
1849
1850 #include <rmr/rmr.h>
1851 int rmr_payload_size( rmr_mbuf_t* msg );
1852
1853
1854
1855DESCRIPTION
1856--------------------------------------------------------------------------------------------
1857
1858Given a message buffer, this function returns the amount of
1859space (bytes) available for the user application to consume
1860in the message payload. This is different than the message
1861length available as a field in the message buffer.
1862
1863RETURN VALUE
1864--------------------------------------------------------------------------------------------
1865
1866The number of bytes available in the payload.
1867
1868ERRORS
1869--------------------------------------------------------------------------------------------
1870
1871
1872
1873INVAL
1874
1875 Parameter(s) passed to the function were not valid.
1876
1877
1878SEE ALSO
1879--------------------------------------------------------------------------------------------
1880
1881rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
1882rmr_send_msg(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
1883rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3),
1884rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3)
1885
1886
1887NAME
1888--------------------------------------------------------------------------------------------
1889
1890rmr_rcv_msg
1891
1892SYNOPSIS
1893--------------------------------------------------------------------------------------------
1894
1895
1896::
1897
1898 #include <rmr/rmr.h>
1899 rmr_mbuf_t* rmr_rcv_msg( void* vctx, rmr_mbuf_t* old_msg );
1900
1901
1902
1903DESCRIPTION
1904--------------------------------------------------------------------------------------------
1905
1906The rmr_rcv_msg function blocks until a message is received,
1907returning the message to the caller via a pointer to a
1908rmr_mbuf_t structure type. If messages were queued while
1909waiting for the response to a previous invocation of
1910rmr_call, the oldest message is removed from the queue and
1911returned without delay.
1912
1913The *vctx* pointer is the pointer returned by the rmr_init
1914function. *Old_msg* is a pointer to a previously used message
1915buffer or NULL. The ability to reuse message buffers helps to
1916avoid alloc/free cycles in the user application. When no
1917buffer is available to supply, the receive function will
1918allocate one.
1919
1920RETURN VALUE
1921--------------------------------------------------------------------------------------------
1922
1923The function returns a pointer to the rmr_mbuf_t structure
1924which references the message information (state, length,
1925payload), or a NULL pointer in the case of an extreme error.
1926
1927ERRORS
1928--------------------------------------------------------------------------------------------
1929
1930The *state* field in the message buffer will indicate either
1931RMR_OK or RMR_ERR_EMPTY if an empty message was received. If
1932a nil pointer is returned, or any other state value was set
1933in the message buffer, errno will be set to one of the
1934following:
1935
1936
1937
1938INVAL
1939
1940 Parameter(s) passed to the function were not valid.
1941
1942
1943EBADF
1944
1945 The underlying message transport is unable to process the
1946 request.
1947
1948
1949ENOTSUP
1950
1951 The underlying message transport is unable to process the
1952 request.
1953
1954
1955EFSM
1956
1957 The underlying message transport is unable to process the
1958 request.
1959
1960
1961EAGAIN
1962
1963 The underlying message transport is unable to process the
1964 request.
1965
1966
1967EINTR
1968
1969 The underlying message transport is unable to process the
1970 request.
1971
1972
1973ETIMEDOUT
1974
1975 The underlying message transport is unable to process the
1976 request.
1977
1978
1979ETERM
1980
1981 The underlying message transport is unable to process the
1982 request.
1983
1984
1985EXAMPLE
1986--------------------------------------------------------------------------------------------
1987
1988
1989SEE ALSO
1990--------------------------------------------------------------------------------------------
1991
1992rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
1993rmr_get_rcvfd(3), rmr_init(3), rmr_mk_ring(3),
1994rmr_payload_size(3), rmr_send_msg(3), rmr_torcv_msg(3),
1995rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
1996rmr_ring_free(3), rmr_torcv_msg(3)
1997
1998
1999NAME
2000--------------------------------------------------------------------------------------------
2001
2002rmr_ready
2003
2004SYNOPSIS
2005--------------------------------------------------------------------------------------------
2006
2007
2008::
2009
2010 #include <rmr/rmr.h>
2011 int rmr_ready( void* vctx );
2012
2013
2014
2015DESCRIPTION
2016--------------------------------------------------------------------------------------------
2017
2018The rmr_ready function checks to see if a routing table has
2019been successfully received and installed. The return value
2020indicates the state of readiness.
2021
2022RETURN VALUE
2023--------------------------------------------------------------------------------------------
2024
2025A return value of 1 (true) indicates that the routing table
2026is in place and attempts to send messages can be made. When 0
2027is returned (false) the routing table has not been received
2028and thus attempts to send messages will fail with *no
2029endpoint* errors.
2030
2031SEE ALSO
2032--------------------------------------------------------------------------------------------
2033
2034rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
2035rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
2036rmr_rcv_specific(3), rmr_rts_msg(3), rmr_fib(3),
2037rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3),
2038rmr_ring_free(3)
2039
2040
2041NAME
2042--------------------------------------------------------------------------------------------
2043
2044rmr_realloc_payload
2045
2046SYNOPSIS
2047--------------------------------------------------------------------------------------------
2048
2049
2050::
2051
2052 #include <rmr/rmr.h>
2053 extern rmr_mbuf_t* rmr_realloc_payload( rmr_mbuf_t* msg, int new_len, int copy, int clone );
2054
2055
2056
2057DESCRIPTION
2058--------------------------------------------------------------------------------------------
2059
2060The rmr_realloc_payload function will return a pointer to an
2061RMR message buffer struct (rmr_mbuf_t) which has a payload
2062large enough to accomodate *new_len* bytes. If necessary, the
2063underlying payload is reallocated, and the bytes from the
2064original payload are copied if the *copy* parameter is true
2065(1). If the message passed in has a payload large enough,
2066there is no additional memory allocation and copying.
2067
2068Cloning The Message Buffer
2069~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2070
2071This function can also be used to generate a separate copy of
2072the original message, with the desired payload size, without
2073destroying the original message buffer or the original
2074payload. A standalone copy is made only when the *clone*
2075parameter is true (1). When cloning, the payload is copied to
2076the cloned message **only** if the *copy* parameter is true.
2077
2078Message Buffer Metadata
2079~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2080
2081The metadata in the original message buffer (message type,
2082subscription ID, and payload length) will be preserved if the
2083*copy* parameter is true. When this parameter is not true
2084(0), then these values are set to the uninitialised value
2085(-1) for type and ID, and the length is set to 0.
2086
2087RETURN VALUE
2088--------------------------------------------------------------------------------------------
2089
2090The rmr_realloc_payload function returns a pointer to the
2091message buffer with the payload which is large enough to hold
2092*new_len* bytes. If the *clone* option is true, this will be
2093a pointer to the newly cloned message buffer; the original
2094message buffer pointer may still be used to referenced that
2095message. It is the calling application's responsibility to
2096free the memory associateed with both messages using the
2097rmr_free_msg() function.
2098
2099When the *clone* option is not used, it is still good
2100practice by the calling application to capture and use this
2101reference as it is possible that the message buffer, and not
2102just the payload buffer, was reallocated. In the event of an
2103error, a nil pointer will be returned and the value of
2104*errno* will be set to reflect the problem.
2105
2106ERRORS
2107--------------------------------------------------------------------------------------------
2108
2109These value of *errno* will reflect the error condition if a
2110nil pointer is returned:
2111
2112
2113
2114ENOMEM
2115
2116 Memory allocation of the new payload failed.
2117
2118
2119EINVAL
2120
2121 The pointer passed in was nil, or refrenced an invalid
2122 message, or the required length was not valid.
2123
2124
2125EXAMPLE
2126--------------------------------------------------------------------------------------------
2127
2128The following code bit illustrates how this function can be
2129used to reallocate a buffer for a return to sender
2130acknowledgement message which is larger than the message
2131received.
2132
2133
2134::
2135
2136 if( rmr_payload_size( msg ) < ack_sz ) { // received message too small for ack
2137 msg = rmr_realloc_payload( msg, ack_sz, 0, 0 ); // reallocate the message with a payload big enough
2138 if( msg == NULL ) {
2139 fprintf( stderr, "[ERR] realloc returned a nil pointer: %s\\n", strerror( errno ) );
2140 } else {
2141 } e// populate and send ack message
2142 }}
2143 }
2144
2145
2146
2147SEE ALSO
2148--------------------------------------------------------------------------------------------
2149
2150rmr_alloc_msg(3), rmr_free_msg(3), rmr_init(3),
2151rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
2152rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
2153rmr_fib(3), rmr_has_str(3), rmr_set_stimeout(3),
2154rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3)
2155
2156
2157NAME
2158--------------------------------------------------------------------------------------------
2159
2160rmr_rts_msg
2161
2162SYNOPSIS
2163--------------------------------------------------------------------------------------------
2164
2165
2166::
2167
2168 #include <rmr/rmr.h>
2169 rmr_mbuf_t* rmr_rts_msg( void* vctx, rmr_mbuf_t* msg );
2170
2171
2172
2173DESCRIPTION
2174--------------------------------------------------------------------------------------------
2175
2176The rmr_rts_msg function sends a message returning it to the
2177endpoint which sent the message rather than selecting an
2178endpoint based on the message type and routing table. Other
2179than this small difference, the behaviour is exactly the same
2180as rmr_send_msg.
2181
2182Retries
2183~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2184
2185The send operations in RMr will retry *soft* send failures
2186until one of three conditions occurs:
2187
2188
2189
21901.
2191
2192 The message is sent without error
2193
2194
21952.
2196
2197 The underlying transport reports a * hard * failure
2198
2199
22003.
2201
2202 The maximum number of retry loops has been attempted
2203
2204
2205A retry loop consists of approximately 1000 send attemps **
2206without** any intervening calls to * sleep() * or * usleep().
2207* The number of retry loops defaults to 1, thus a maximum of
22081000 send attempts is performed before returning to the user
2209application. This value can be set at any point after RMr
2210initialisation using the * rmr_set_stimeout() * function
2211allowing the user application to completely disable retires
2212(set to 0), or to increase the number of retry loops.
2213
2214Transport Level Blocking
2215~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2216
2217The underlying transport mechanism used to send messages is
2218configured in *non-blocking* mode. This means that if a
2219message cannot be sent immediately the transport mechanism
2220will **not** pause with the assumption that the inability to
2221send will clear quickly (within a few milliseconds). This
2222means that when the retry loop is completely disabled (set to
22230), that the failure to accept a message for sending by the
2224underlying mechanisms (software or hardware) will be reported
2225immediately to the user application.
2226
2227It should be noted that depending on the underlying transport
2228mechanism being used, it is extremly possible that during
2229normal operations that retry conditions are very likely to
2230happen. These are completely out of RMr's control, and there
2231is nothing that RMr can do to avoid or midigate these other
2232than by allowing RMr to retry the send operation, and even
2233then it is possible (e.g. during connection reattempts), that
2234a single retry loop is not enough to guarentee a successful
2235send.
2236
2237PAYLOAD SIZE
2238--------------------------------------------------------------------------------------------
2239
2240When crafting a response based on a received message, the
2241user application must take care not to write more bytes to
2242the message payload than the allocated message has. In the
2243case of a received message, it is possible that the response
2244needs to be larger than the payload associated with the
2245inbound message. In order to use the return to sender
2246function, the source infomration in the orignal message must
2247be present in the response; information which cannot be added
2248to a message buffer allocated through the standard RMR
2249allocation function. To allocate a buffer with a larger
2250payload, and which retains the necessary sender data needed
2251by this function, the *rmr_realloc_payload()* function must
2252be used to extend the payload to a size suitable for the
2253response.
2254
2255RETURN VALUE
2256--------------------------------------------------------------------------------------------
2257
2258On success, a new message buffer, with an empty payload, is
2259returned for the application to use for the next send. The
2260state in this buffer will reflect the overall send operation
2261state and should be RMR_OK.
2262
2263If the state in the returned buffer is anything other than
2264UT_OK, the user application may need to attempt a
2265retransmission of the message, or take other action depending
2266on the setting of errno as described below.
2267
2268In the event of extreme failure, a NULL pointer is returned.
2269In this case the value of errno might be of some use, for
2270documentation, but there will be little that the user
2271application can do other than to move on.
2272
2273ERRORS
2274--------------------------------------------------------------------------------------------
2275
2276The following values may be passed back in the *state* field
2277of the returned message buffer.
2278
2279
2280
2281RMR_ERR_BADARG
2282
2283 The message buffer pointer did not refer to a valid
2284 message.
2285
2286RMR_ERR_NOHDR
2287
2288 The header in the message buffer was not valid or
2289 corrupted.
2290
2291RMR_ERR_NOENDPT
2292
2293 The message type in the message buffer did not map to a
2294 known endpoint.
2295
2296RMR_ERR_SENDFAILED
2297
2298 The send failed; errno has the possible reason.
2299
2300
2301The following values may be assigned to errno on failure.
2302
2303
2304INVAL
2305
2306 Parameter(s) passed to the function were not valid, or the
2307 underlying message processing environment was unable to
2308 interpret the message.
2309
2310
2311ENOKEY
2312
2313 The header information in the message buffer was invalid.
2314
2315
2316ENXIO
2317
2318 No known endpoint for the message could be found.
2319
2320
2321EMSGSIZE
2322
2323 The underlying transport refused to accept the message
2324 because of a size value issue (message was not attempted
2325 to be sent).
2326
2327
2328EFAULT
2329
2330 The message referenced by the message buffer is corrupt
2331 (NULL pointer or bad internal length).
2332
2333
2334EBADF
2335
2336 Internal RMR error; information provided to the message
2337 transport environment was not valid.
2338
2339
2340ENOTSUP
2341
2342 Sending was not supported by the underlying message
2343 transport.
2344
2345
2346EFSM
2347
2348 The device is not in a state that can accept the message.
2349
2350
2351EAGAIN
2352
2353 The device is not able to accept a message for sending.
2354 The user application should attempt to resend.
2355
2356
2357EINTR
2358
2359 The operation was interrupted by delivery of a signal
2360 before the message was sent.
2361
2362
2363ETIMEDOUT
2364
2365 The underlying message environment timed out during the
2366 send process.
2367
2368
2369ETERM
2370
2371 The underlying message environment is in a shutdown state.
2372
2373
2374EXAMPLE
2375--------------------------------------------------------------------------------------------
2376
2377
2378SEE ALSO
2379--------------------------------------------------------------------------------------------
2380
2381rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
2382rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
2383rmr_rcv_specific(3), rmr_ready(3), rmr_fib(3),
2384rmr_has_str(3), rmr_set_stimeout(3), rmr_tokenise(3),
2385rmr_mk_ring(3), rmr_ring_free(3)
2386
2387
2388NAME
2389--------------------------------------------------------------------------------------------
2390
2391rmr_send_msg
2392
2393SYNOPSIS
2394--------------------------------------------------------------------------------------------
2395
2396
2397::
2398
2399 #include <rmr/rmr.h>
2400 rmr_mbuf_t* rmr_send_msg( void* vctx, rmr_mbuf_t* msg );
2401
2402
2403
2404DESCRIPTION
2405--------------------------------------------------------------------------------------------
2406
2407The rmr_send_msg function accepts a message buffer from the
2408user application and attempts to send it. The destination of
2409the message is selected based on the message type specified
2410in the message buffer, and the matching information in the
2411routing tables which are currently in use by the RMR library.
2412This may actually result in the sending of the message to
2413multiple destinations which could degrade expected overall
2414performance of the user application. (Limiting excessive
2415sending of messages is the responsibility of the
2416application(s) responsible for building the routing table
2417used by the RMR library, and not the responsibility of the
2418library.)
2419
2420Retries
2421~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2422
2423The send operations in RMr will retry *soft* send failures
2424until one of three conditions occurs:
2425
2426
2427
24281.
2429
2430 The message is sent without error
2431
2432
24332.
2434
2435 The underlying transport reports a * hard * failure
2436
2437
24383.
2439
2440 The maximum number of retry loops has been attempted
2441
2442
2443A retry loop consists of approximately 1000 send attemps **
2444without** any intervening calls to * sleep() * or * usleep().
2445* The number of retry loops defaults to 1, thus a maximum of
24461000 send attempts is performed before returning to the user
2447application. This value can be set at any point after RMr
2448initialisation using the * rmr_set_stimeout() * function
2449allowing the user application to completely disable retires
2450(set to 0), or to increase the number of retry loops.
2451
2452Transport Level Blocking
2453~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2454
2455The underlying transport mechanism used to send messages is
2456configured in *non-blocking* mode. This means that if a
2457message cannot be sent immediately the transport mechanism
2458will **not** pause with the assumption that the inability to
2459send will clear quickly (within a few milliseconds). This
2460means that when the retry loop is completely disabled (set to
24610), that the failure to accept a message for sending by the
2462underlying mechanisms (software or hardware) will be reported
2463immediately to the user application.
2464
2465It should be noted that depending on the underlying transport
2466mechanism being used, it is extremly possible that during
2467normal operations that retry conditions are very likely to
2468happen. These are completely out of RMr's control, and there
2469is nothing that RMr can do to avoid or midigate these other
2470than by allowing RMr to retry the send operation, and even
2471then it is possible (e.g. during connection reattempts), that
2472a single retry loop is not enough to guarentee a successful
2473send.
2474
2475RETURN VALUE
2476--------------------------------------------------------------------------------------------
2477
2478On success, a new message buffer, with an empty payload, is
2479returned for the application to use for the next send. The
2480state in this buffer will reflect the overall send operation
E. Scott Danielsa1575da2020-01-24 16:00:11 -05002481state and will be RMR_OK when the send was successful.
E. Scott Daniels392168d2019-11-06 15:12:38 -05002482
2483When the message cannot be successfully sent this function
2484will return the unsent (original) message buffer with the
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05002485state set to indicate the reason for failure. The value of
2486*errno* may also be set to reflect a more detailed failure
E. Scott Daniels392168d2019-11-06 15:12:38 -05002487reason if it is known.
2488
2489In the event of extreme failure, a NULL pointer is returned.
2490In this case the value of errno might be of some use, for
2491documentation, but there will be little that the user
2492application can do other than to move on.
2493
E. Scott Danielsa1575da2020-01-24 16:00:11 -05002494**CAUTION:** In some cases it is extremely likely that the
2495message returned by the send function does **not** reference
2496the same memory structure. Thus is important for the user
2497programme to capture the new pointer for future use or to be
2498passed to rmr_free(). If you are experiencing either double
2499free errors or segment faults in either rmr_free() or
2500rmr_send_msg(), ensure that the return value from this
2501function is being captured and used.
2502
E. Scott Daniels392168d2019-11-06 15:12:38 -05002503ERRORS
2504--------------------------------------------------------------------------------------------
2505
2506The following values may be passed back in the *state* field
2507of the returned message buffer.
2508
2509
2510
2511RMR_RETRY
2512
2513 The message could not be sent, but the underlying
2514 transport mechanism indicates that the failure is
2515 temporary. If the send operation is tried again it might
2516 be successful.
2517
2518RMR_SEND_FAILED
2519
2520 The send operation was not successful and the underlying
2521 transport mechanism indicates a permanent (hard) failure;
2522 retrying the send is not possible.
2523
2524RMR_ERR_BADARG
2525
2526 The message buffer pointer did not refer to a valid
2527 message.
2528
2529RMR_ERR_NOHDR
2530
2531 The header in the message buffer was not valid or
2532 corrupted.
2533
2534RMR_ERR_NOENDPT
2535
2536 The message type in the message buffer did not map to a
2537 known endpoint.
2538
2539
2540The following values may be assigned to errno on failure.
2541
2542
2543INVAL
2544
2545 Parameter(s) passed to the function were not valid, or the
2546 underlying message processing environment was unable to
2547 interpret the message.
2548
2549
2550ENOKEY
2551
2552 The header information in the message buffer was invalid.
2553
2554
2555ENXIO
2556
2557 No known endpoint for the message could be found.
2558
2559
2560EMSGSIZE
2561
2562 The underlying transport refused to accept the message
2563 because of a size value issue (message was not attempted
2564 to be sent).
2565
2566
2567EFAULT
2568
2569 The message referenced by the message buffer is corrupt
2570 (NULL pointer or bad internal length).
2571
2572
2573EBADF
2574
2575 Internal RMR error; information provided to the message
2576 transport environment was not valid.
2577
2578
2579ENOTSUP
2580
2581 Sending was not supported by the underlying message
2582 transport.
2583
2584
2585EFSM
2586
2587 The device is not in a state that can accept the message.
2588
2589
2590EAGAIN
2591
2592 The device is not able to accept a message for sending.
2593 The user application should attempt to resend.
2594
2595
2596EINTR
2597
2598 The operation was interrupted by delivery of a signal
2599 before the message was sent.
2600
2601
2602ETIMEDOUT
2603
2604 The underlying message environment timed out during the
2605 send process.
2606
2607
2608ETERM
2609
2610 The underlying message environment is in a shutdown state.
2611
2612
2613EXAMPLE
2614--------------------------------------------------------------------------------------------
2615
2616The following is a simple example of how the rmr_send_msg
2617function is called. In this example, the send message buffer
2618is saved between calls and reused eliminating alloc/free
2619cycles.
2620
2621
2622::
2623
2624 static rmr_mbuf_t* send_msg = NULL; // message to send; reused on each call
2625 msg_t* send_pm; // payload for send
2626 msg_t* pm; // our message format in the received payload
2627 mif( send_msg == NULL ) {
2628 send_msg = rmr_alloc_msg( mr, MAX_SIZE ); r// new buffer to send
2629 }
2630 // reference payload and fill in message type
2631 pm = (msg_t*) send_msg->payload;
E. Scott Danielsa1575da2020-01-24 16:00:11 -05002632 send_msg->mtype = MT_ANSWER;
2633 msg->len = generate_data( pm ); // something that fills the payload in
2634 msg = rmr_send_msg( mr, send_msg ); // ensure new pointer used after send
E. Scott Daniels392168d2019-11-06 15:12:38 -05002635 mif( ! msg ) {
2636 m !return ERROR;
2637 m} else {
2638 m sif( msg->state != RMR_OK ) {
E. Scott Danielsa1575da2020-01-24 16:00:11 -05002639 m s m// check for RMR_ERR_RETRY, and resend if needed
E. Scott Daniels392168d2019-11-06 15:12:38 -05002640 m s m// else return error
2641 m s}
2642 m}
2643 mreturn OK;
E. Scott Daniels392168d2019-11-06 15:12:38 -05002644
2645
2646
2647SEE ALSO
2648--------------------------------------------------------------------------------------------
2649
2650rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
2651rmr_payload_size(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
2652rmr_rts_msg(3), rmr_ready(3), rmr_mk_ring(3),
2653rmr_ring_free(3), rmr_torcv_rcv(3), rmr_wh_send_msg(3)
2654
2655
2656NAME
2657--------------------------------------------------------------------------------------------
2658
2659rmr_set_stimeout
2660
2661SYNOPSIS
2662--------------------------------------------------------------------------------------------
2663
2664
2665::
2666
2667 #include <rmr/rmr.h>
2668 rmr_mbuf_t* rmr_set_stimeout( void* vctx, int rloops );
2669
2670
2671
2672DESCRIPTION
2673--------------------------------------------------------------------------------------------
2674
2675The rmr_set_stimeout function sets the configuration for how
2676RMr will retry message send operations which complete with
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05002677either a *timeout* or *again* completion value. (Send
E. Scott Daniels392168d2019-11-06 15:12:38 -05002678operations include all of the possible message send
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05002679functions: *rmr_send_msg(), rmr_call(), rmr_rts_msg()* and
2680*rmr_wh_send_msg().* The *rloops* parameter sets the maximum
2681number of retry loops that will be attempted before giving up
2682and returning the unsuccessful state to the user application.
2683Each retry loop is approximately 1000 attempts, and RMr does
2684**not** invoke any sleep function between retries in the
2685loop; a small, 1 mu-sec, sleep is executed between loop sets
2686if the *rloops* value is greater than 1.
E. Scott Daniels392168d2019-11-06 15:12:38 -05002687
2688
2689Disabling Retries
2690~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2691
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05002692By default, the send operations will execute with an *rloop*
2693setting of 1; each send operation will attempt to resend the
2694message approximately 1000 times before giving up. If the
E. Scott Daniels392168d2019-11-06 15:12:38 -05002695user application does not want to have send operations retry
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05002696when the underlying transport mechanism indicates *timeout*
2697or *again,* the application should invoke this function and
2698pass a value of 0 (zero) for *rloops.* With this setting, all
2699RMr send operations will attempt a send operation only
2700**once,** returning immediately to the caller with the state
E. Scott Daniels392168d2019-11-06 15:12:38 -05002701of that single attempt.
2702
2703RETURN VALUE
2704--------------------------------------------------------------------------------------------
2705
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05002706This function returns a -1 to indicate that the *rloops*
2707value could not be set, and the value *RMR_OK* to indicate
E. Scott Daniels392168d2019-11-06 15:12:38 -05002708success.
2709
2710ERRORS
2711--------------------------------------------------------------------------------------------
2712
E. Scott Danielsb7a4b522019-11-07 15:35:17 -05002713Currently errno is **not** set by this function; the only
2714cause of a failure is an invalid context (*vctx*) pointer.
E. Scott Daniels392168d2019-11-06 15:12:38 -05002715
2716EXAMPLE
2717--------------------------------------------------------------------------------------------
2718
2719The following is a simple example of how the rmr_set_stimeout
2720function is called.
2721
2722
2723::
2724
2725 #define NO_FLAGS 0
2726 char* Oport = "43086"; // port for message router listen
2727 int rmax_size = 4096; // max message size for default allocations
2728 void* mr_context; // message router context
2729 mr_context = rmr_init( port, max_size, NO_FLAGS );
2730 if( mr_context != NULL ) {
2731 rmr_set_stimeout( mr_context, 0 ); // turn off retries
2732 }
2733
2734
2735
2736SEE ALSO
2737--------------------------------------------------------------------------------------------
2738
2739rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
2740rmr_payload_size(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
2741rmr_rts_msg(3), rmr_ready(3), rmr_mk_ring(3),
2742rmr_ring_free(3), rmr_send_msg(3), rmr_torcv_rcv(3),
2743rmr_wh_send_msg(3)
2744
2745
2746NAME
2747--------------------------------------------------------------------------------------------
2748
2749rmr_set_trace
2750
2751SYNOPSIS
2752--------------------------------------------------------------------------------------------
2753
2754
2755::
2756
2757 #include <rmr/rmr.h>
2758 int rmr_bytes2payload( rmr_mbuf_t* mbuf, unsigned char* data, int len )
2759
2760
2761
2762DESCRIPTION
2763--------------------------------------------------------------------------------------------
2764
2765The rmr_set_trace function will copy len bytes from data into
2766the trace portion of mbuf. If the trace area of mbuf is not
2767the correct size, the message buffer will be reallocated to
2768ensure that enough space is available for the trace data.
2769
2770RETURN VALUE
2771--------------------------------------------------------------------------------------------
2772
2773The rmr_set_trace function returns the number of bytes
2774successfully copied to the message. If 0 is returned either
2775the message pointer was nil, or the size in the parameters
2776was <= 0.
2777
2778SEE ALSO
2779--------------------------------------------------------------------------------------------
2780
2781rmr_alloc_msg(3), rmr_tralloc_msg(3), rmr_bytes2xact(3),
2782rmr_bytes2payload(3), rmr_call(3), rmr_free_msg(3),
2783rmr_get_rcvfd(3), rmr_get_meid(3), rmr_get_trace(3),
2784rmr_get_trlen(3), rmr_init(3), rmr_init_trace(3),
2785rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
2786rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
2787rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3),
2788rmr_ring_free(3), rmr_str2meid(3), rmr_str2xact(3),
2789rmr_wh_open(3), rmr_wh_send_msg(3)
2790
2791
2792NAME
2793--------------------------------------------------------------------------------------------
2794
2795rmr_str2meid
2796
2797SYNOPSIS
2798--------------------------------------------------------------------------------------------
2799
2800
2801::
2802
2803 #include <rmr/rmr.h>
2804 int rmr_str2meid( rmr_mbuf_t* mbuf, unsigned char* src, int len )
2805
2806
2807
2808DESCRIPTION
2809--------------------------------------------------------------------------------------------
2810
2811The rmr_str2meid function will copy the string pointed to by
E. Scott Daniels190665f2019-12-09 09:05:22 -05002812src to the managed entity ID (meid) field in the given
E. Scott Daniels392168d2019-11-06 15:12:38 -05002813message. The field is a fixed length, gated by the constant
2814RMR_MAX_MEID and if string length is larger than this value,
2815then **nothing** will be copied. (Note, this differs slightly
2816from the behaviour of the lrmr_bytes2meid() function.)
2817
2818RETURN VALUE
2819--------------------------------------------------------------------------------------------
2820
2821On success, the value RMR_OK is returned. If the string
2822cannot be copied to the message, the return value will be one
2823of the errors listed below.
2824
2825ERRORS
2826--------------------------------------------------------------------------------------------
2827
2828If the return value is not RMR_OK, then it will be set to one
2829of the values below.
2830
2831
2832
2833RMR_ERR_BADARG
2834
2835 The message, or an internal portion of the message, was
2836 corrupted or the pointer was invalid.
2837
2838
2839RMR_ERR_OVERFLOW
2840
2841 The length passed in was larger than the maximum length of
2842 the field; only a portion of the source bytes were copied.
2843
2844
2845EXAMPLE
2846--------------------------------------------------------------------------------------------
2847
2848
2849SEE ALSO
2850--------------------------------------------------------------------------------------------
2851
2852rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
2853rmr_get_meid(3), rmr_get_rcvfd(3), rmr_payload_size(3),
2854rmr_send_msg(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
2855rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3),
2856rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3),
2857rmr_bytes2meid(3), rmr_wh_open(3), rmr_wh_send_msg(3)
2858
2859
2860NAME
2861--------------------------------------------------------------------------------------------
2862
2863rmr_str2xact
2864
2865SYNOPSIS
2866--------------------------------------------------------------------------------------------
2867
2868
2869::
2870
2871 #include <rmr/rmr.h>
2872 int rmr_str2xact( rmr_mbuf_t* mbuf, unsigned char* src, int len )
2873
2874
2875
2876DESCRIPTION
2877--------------------------------------------------------------------------------------------
2878
2879The rmr_str2xact function will copy the string pointed to by
2880src to the transaction ID (xaction) field in the given
2881message. The field is a fixed length, gated by the constant
2882RMR_MAX_XID and if string length is larger than this value,
2883then **nothing** will be copied. (Note, this differs slightly
2884from the behaviour of the lrmr_bytes2xact() function.)
2885
2886
2887RETURN VALUE
2888--------------------------------------------------------------------------------------------
2889
2890On success, the value RMR_OK is returned. If the string
2891cannot be copied to the message, the return value will be
2892one of the errors listed below.
2893
2894ERRORS
2895--------------------------------------------------------------------------------------------
2896
2897If the return value is not RMR_OK, then it will be set to
2898one of the values below.
2899
2900
2901RMR_ERR_BADARG
2902
2903 The message, or an internal portion of the message, was
2904 corrupted or the pointer was invalid.
2905
2906
2907RMR_ERR_OVERFLOW
2908
2909 The length passed in was larger than the maximum length of
2910 the field; only a portion of the source bytes were copied.
2911
2912
2913EXAMPLE
2914--------------------------------------------------------------------------------------------
2915
2916
2917SEE ALSO
2918--------------------------------------------------------------------------------------------
2919
2920rmr_alloc_msg(3), rmr_bytes2meid(3), rmr_bytes2xact(3),
2921rmr_call(3), rmr_free_msg(3), rmr_get_meid(3),
2922rmr_get_rcvfd(3), rmr_get_xact(3), rmr_payload_size(3),
2923rmr_send_msg(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
2924rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3),
2925rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3),
2926rmr_str2meid(3), rmr_wh_open(3), rmr_wh_send_msg(3)
2927
2928
2929NAME
2930--------------------------------------------------------------------------------------------
2931
2932RMR support functions
2933
2934SYNOPSIS
2935--------------------------------------------------------------------------------------------
2936
2937
2938::
2939
2940 #include <rmr/rmr.h>
2941 #include <rmr/ring_inline.h>
2942 char* rmr_fib( char* fname );
2943 int rmr_has_str( char const* buf, char const* str, char sep, int max );
2944 int rmr_tokenise( char* buf, char** tokens, int max, char sep );
2945 void* rmr_mk_ring( int size );
2946 void rmr_ring_free( void* vr );
2947 static inline void* rmr_ring_extract( void* vr )
2948 static inline int rmr_ring_insert( void* vr, void* new_data )
2949
2950
2951
2952DESCRIPTION
2953--------------------------------------------------------------------------------------------
2954
2955These functions support the RMR library, and are made
2956available to user applications as some (e.g. route table
2957generators) might need and/or want to make use of them. The
2958rmr_fib function accepts a file name and reads the entire
2959file into a single buffer. The intent is to provide an easy
2960way to load a static route table without a lot of buffered
2961I/O hoops.
2962
2963The rmr_has_str function accepts a *buffer* containing a set
2964of delimited tokens (e.g. foo,bar,goo) and returns true if
2965the target string, *str,* matches one of the tokens. The
2966*sep* parameter provides the separation character in the
2967buffer (e.g a comma) and *max* indicates the maximum number
2968of tokens to split the buffer into before checking.
2969
2970The rmr_tokenise function is a simple tokeniser which splits
2971*buf* into tokens at each occurrence of *sep*. Multiple
2972occurrences of the separator character (e.g. a,,b) result in
2973a nil token. Pointers to the tokens are placed into the
2974*tokens* array provided by the caller which is assumed to
2975have at least enough space for *max* entries.
2976
2977The rmr_mk_ring function creates a buffer ring with *size*
2978entries.
2979
2980The rmr_ring_free function accepts a pointer to a ring
2981context and frees the associated memory.
2982
2983The rmr_ring_insert and rmr_ring_extract functions are
2984provided as static inline functions via the
2985*rmr/ring_inline.h* header file. These functions both accept
2986the ring *context* returned by mk_ring, and either insert a
2987pointer at the next available slot (tail) or extract the data
2988at the head.
2989
2990RETURN VALUES
2991--------------------------------------------------------------------------------------------
2992
2993The following are the return values for each of these
2994functions.
2995
2996The rmr_fib function returns a pointer to the buffer
2997containing the contents of the file. The buffer is terminated
2998with a single nil character (0) making it a legitimate C
2999string. If the file was empty or nonexistent, a buffer with
3000an immediate nil character. If it is important to the calling
3001programme to know if the file was empty or did not exist, the
3002caller should use the system stat function call to make that
3003determination.
3004
3005The rmr_has_str function returns 1 if *buf* contains the
3006token referenced by &ita and false (0) if it does not. On
3007error, a -1 value is returned and errno is set accordingly.
3008
3009The rmr_tokenise function returns the actual number of token
3010pointers placed into *tokens*
3011
3012The rmr_mk_ring function returns a void pointer which is the
3013*context* for the ring.
3014
3015The rmr_ring_insert function returns 1 if the data was
3016successfully inserted into the ring, and 0 if the ring is
3017full and the pointer could not be deposited.
3018
3019The rmr_ring_extract will return the data which is at the
3020head of the ring, or NULL if the ring is empty.
3021
3022ERRORS
3023--------------------------------------------------------------------------------------------
3024
3025Not many of these functions set the value in errno, however
3026the value may be one of the following:
3027
3028
3029INVAL
3030
3031 Parameter(s) passed to the function were not valid.
3032
3033
3034EXAMPLE
3035--------------------------------------------------------------------------------------------
3036
3037
3038SEE ALSO
3039--------------------------------------------------------------------------------------------
3040
3041rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
3042rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
3043rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
3044
3045
3046NAME
3047--------------------------------------------------------------------------------------------
3048
3049rmr_torcv_msg
3050
3051SYNOPSIS
3052--------------------------------------------------------------------------------------------
3053
3054
3055::
3056
3057 #include <rmr/rmr.h>
3058 rmr_mbuf_t* rmr_torcv_msg( void* vctx, rmr_mbuf_t* old_msg, int ms_to );
3059
3060
3061
3062DESCRIPTION
3063--------------------------------------------------------------------------------------------
3064
3065The rmr_torcv_msg function will pause for *ms_to*
3066milliseconds waiting for a message to arrive. If a message
3067arrives before the timeout expires the message buffer
3068returned will have a status of RMR_OK and the payload will
3069contain the data received. If the timeout expires before the
3070message is received, the status will have the value
3071RMR_ERR_TIMEOUT. When a received message is returned the
3072message buffer will also contain the message type and length
3073set by the sender. If messages were queued while waiting for
3074the response to a previous invocation of rmr_call, the oldest
3075message is removed from the queue and returned without delay.
3076
3077The *vctx* pointer is the pointer returned by the rmr_init
3078function. *Old_msg* is a pointer to a previously used message
3079buffer or NULL. The ability to reuse message buffers helps to
3080avoid alloc/free cycles in the user application. When no
3081buffer is available to supply, the receive function will
3082allocate one.
3083
3084RETURN VALUE
3085--------------------------------------------------------------------------------------------
3086
3087The function returns a pointer to the rmr_mbuf_t structure
3088which references the message information (state, length,
3089payload), or a NULL pointer in the case of an extreme error.
3090
3091ERRORS
3092--------------------------------------------------------------------------------------------
3093
3094The *state* field in the message buffer will be one of the
3095following:
3096
3097
3098
3099RMR_OK
3100
3101 The message buffer (payload) references the received data.
3102
3103
3104RMR_ERR_INITFAILED
3105
3106 The first call to this function must initialise an
3107 underlying system notification mechanism. On failure, this
3108 error is returned and errno will have the system error
3109 status set. If this function fails to intialise, the poll
3110 mechansim, it is likely that message receives will never
3111 be successful.
3112
3113
3114RMR_ERR_TIMEOUT
3115
3116 The timeout expired before a complete message was
3117 received. All other fields in the message buffer are not
3118 valid.
3119
3120
3121RMR_ERR_EMPTY
3122
3123 A message was received, but it had no payload. All other
3124 fields in the message buffer are not valid.
3125
3126
3127
3128
3129INVAL
3130
3131 Parameter(s) passed to the function were not valid.
3132
3133
3134EBADF
3135
3136 The underlying message transport is unable to process the
3137 request.
3138
3139
3140ENOTSUP
3141
3142 The underlying message transport is unable to process the
3143 request.
3144
3145
3146EFSM
3147
3148 The underlying message transport is unable to process the
3149 request.
3150
3151
3152EAGAIN
3153
3154 The underlying message transport is unable to process the
3155 request.
3156
3157
3158EINTR
3159
3160 The underlying message transport is unable to process the
3161 request.
3162
3163
3164ETIMEDOUT
3165
3166 The underlying message transport is unable to process the
3167 request.
3168
3169
3170ETERM
3171
3172 The underlying message transport is unable to process the
3173 request.
3174
3175
3176EXAMPLE
3177--------------------------------------------------------------------------------------------
3178
3179
3180SEE ALSO
3181--------------------------------------------------------------------------------------------
3182
3183rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
3184rmr_get_rcvfd(3), rmr_init(3), rmr_payload_size(3),
3185rmr_rcv_msg(3), rmr_send_msg(3), rmr_rcv_specific(3),
3186rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3),
3187rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3)
3188
3189
3190NAME
3191--------------------------------------------------------------------------------------------
3192
3193rmr_trace_ref
3194
3195SYNOPSIS
3196--------------------------------------------------------------------------------------------
3197
3198
3199::
3200
3201 #include <rmr/rmr.h>
3202 int rmr_trace_ref( rmr_mbuf_t* mbuf, int* sizeptr )
3203
3204
3205
3206DESCRIPTION
3207--------------------------------------------------------------------------------------------
3208
3209The rmr_trace_ref function return a pointer to the trace area
3210in the message, and optionally populate the user programme
3211supplied size integer with the trace area size, if *sizeptr*
3212is not nil.
3213
3214RETURN VALUE
3215--------------------------------------------------------------------------------------------
3216
3217On success, a void pointer to the trace area of the message
3218is returned. A nil pointer is returned if the message has no
3219trace data area allocated, or if the message itself is
3220invalid.
3221
3222SEE ALSO
3223--------------------------------------------------------------------------------------------
3224
3225rmr_alloc_msg(3), rmr_tralloc_msg(3), rmr_bytes2xact(3),
3226rmr_bytes2meid(3), rmr_call(3), rmr_free_msg(3),
3227rmr_get_rcvfd(3), rmr_get_trlen(3), rmr_init(3),
3228rmr_init_trace(3), rmr_payload_size(3), rmr_send_msg(3),
3229rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
3230rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
3231rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3),
3232rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3),
3233rmr_set_trace(3)
3234
3235
3236NAME
3237--------------------------------------------------------------------------------------------
3238
3239rmr_tralloc_msg
3240
3241SYNOPSIS
3242--------------------------------------------------------------------------------------------
3243
3244
3245::
3246
3247 #include <rmr/rmr.h>
3248 rmr_mbuf_t* rmr_tralloc_msg( void* vctx, int size,
3249 int trace_size, unsigned const char *tr_data );
3250
3251
3252
3253DESCRIPTION
3254--------------------------------------------------------------------------------------------
3255
3256The rmr_alloc_msg function is used to allocate a buffer which
3257the user programme can write into and then send through the a
3258library. The buffer is allocated such that sending it
3259requires no additional copying from the buffer as it passes
3260through the underlying transport mechanism.
3261
3262The *size* parameter is used to set the payload length in the
3263message and If it is 0, then the default size supplied on the
3264*rmr_init* call will be used. In addition to allocating the
3265payload, a space in the buffer is reserved for *trace* data
3266(tr_size bytes), and the bytes pointed to by *tr_data* are
3267copied into that portion of the message. The *vctx* parameter
3268is the void context pointer that was returned by the
3269*rmr_init* function.
3270
3271The pointer to the message buffer returned is a structure
3272which has some user application visible fields; the structure
3273is described in rmr.h, and is illustrated below.
3274
3275
3276::
3277
3278 typedef struct {
3279 int state;
3280 int mtype;
3281 int len;
3282 unsigned char* payload;
3283 unsigned char* xaction;
3284 } rmr_mbuf_t;
3285
3286
3287
3288
3289
3290state
3291
3292 Is the current buffer state. Following a call to
3293 rmr_send_msg the state indicates whether the buffer was
3294 successfully sent which determines exactly what the
3295 payload points to. If the send failed, the payload
3296 referenced by the buffer is the message that failed to
3297 send (allowing the application to attempt a
3298 retransmission). When the state is a_OK the buffer
3299 represents an empty buffer that the application may fill
3300 in in preparation to send.
3301
3302
3303mtype
3304
3305 When sending a message, the application is expected to set
3306 this field to the appropriate message type value (as
3307 determined by the user programme). Upon send this value
3308 determines how the a library will route the message. For a
3309 buffer which has been received, this field will contain
3310 the message type that was set by the sending application.
3311
3312
3313len
3314
3315 The application using a buffer to send a message is
3316 expected to set the length value to the actual number of
3317 bytes that it placed into the message. This is likely less
3318 than the total number of bytes that the message can carry.
3319 For a message buffer that is passed to the application as
3320 the result of a receive call, this will be the value that
3321 the sending application supplied and should indicate the
3322 number of bytes in the payload which are valid.
3323
3324
3325payload
3326
3327 The payload is a pointer to the actual received data. The
3328 user programme may read and write from/to the memory
3329 referenced by the payload up until the point in time that
3330 the buffer is used on a rmr_send, rmr_call or rmr_reply
3331 function call. Once the buffer has been passed back to a a
3332 library function the user programme should **NOT** make
3333 use of the payload pointer.
3334
3335
3336xaction
3337
3338 The *xaction* field is a pointer to a fixed sized area in
3339 the message into which the user may write a transaction
3340 ID. The ID is optional with the exception of when the user
3341 application uses the rmr_call function to send a message
3342 and wait for the reply; the underlying a processing
3343 expects that the matching reply message will also contain
3344 the same data in the *xaction* field.
3345
3346
3347RETURN VALUE
3348--------------------------------------------------------------------------------------------
3349
3350The function returns a pointer to a rmr_mbuf structure, or
3351NULL on error.
3352
3353ERRORS
3354--------------------------------------------------------------------------------------------
3355
3356
3357
3358ENOMEM
3359
3360 Unable to allocate memory.
3361
3362
3363SEE ALSO
3364--------------------------------------------------------------------------------------------
3365
3366rmr_alloc_msg(3), rmr_mbuf(3) rmr_call(3), rmr_free_msg(3),
3367rmr_init(3), rmr_init_trace(3), rmr_get_trace(3),
3368rmr_get_trlen(3), rmr_payload_size(3), rmr_send_msg(3),
3369rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
3370rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
3371rmr_mk_ring(3), rmr_ring_free(3), rmr_set_trace(3)
3372
3373
3374NAME
3375--------------------------------------------------------------------------------------------
3376
3377rmr_wh_open
3378
3379SYNOPSIS
3380--------------------------------------------------------------------------------------------
3381
3382
3383::
3384
3385 #include <rmr/rmr.h>
3386 void rmr_close( void* vctx, rmr_whid_t whid )
3387
3388
3389
3390DESCRIPTION
3391--------------------------------------------------------------------------------------------
3392
3393The rmr_wh_close function closes the wormhole associated with
3394the wormhole id passed in. Future calls to rmr_wh_send_msg
3395with this ID will fail.
3396
3397The underlying TCP connection to the remote endpoint is
3398**not** closed as this session may be reqruired for
3399regularlly routed messages (messages routed based on message
3400type). There is no way to force a TCP session to be closed at
3401this point in time.
3402
3403SEE ALSO
3404--------------------------------------------------------------------------------------------
3405
3406rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
3407rmr_get_rcvfd(3), rmr_payload_size(3), rmr_send_msg(3),
3408rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
3409rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
3410rmr_mk_ring(3), rmr_ring_free(3), rmr_wh_open(3),
3411rmr_wh_send_msg(3)
3412
3413
3414NAME
3415--------------------------------------------------------------------------------------------
3416
3417rmr_wh_open
3418
3419SYNOPSIS
3420--------------------------------------------------------------------------------------------
3421
3422
3423::
3424
3425 #include <rmr/rmr.h>
3426 void* rmr_wh_open( void* vctx, char* target )
3427
3428
3429
3430DESCRIPTION
3431--------------------------------------------------------------------------------------------
3432
3433The rmr_wh_open function creates a direct link for sending, a
3434wormhole, to another RMr based process. Sending messages
3435through a wormhole requires that the connection be
3436established overtly by the user application (via this
3437function), and that the ID returned by rmr_wh_open be passed
3438to the rmr_wh_send_msg function.
3439
3440*Target* is the *name* or *IP-address* combination of the
3441processess that the wormhole should be connected to. *Vctx*
3442is the RMr void context pointer that was returned by the
3443rmr_init function.
3444
3445When invoked, this function immediatly attempts to connect to
3446the target process. If the connection cannot be established,
3447an error is returned to the caller, and no direct messages
3448can be sent to the target. Once a wormhole is connected, the
3449underlying transport mechanism (e.g. NNG) will provide
3450reconnects should the connection be lost, however the
3451handling of messages sent when a connection is broken is
3452undetermined as each underlying transport mechanism may
3453handle buffering and retries differently.
3454
3455RETURN VALUE
3456--------------------------------------------------------------------------------------------
3457
3458The rmr_wh_open function returns a type rmr_whid_t which must
3459be passed to the rmr_wh_send_msg function when sending a
3460message. The id may also be tested to determine success or
3461failure of the connection by using the RMR_WH_CONNECTED macro
3462and passing the ID as the parameter; a result of 1 indicates
3463that the connection was esablished and that the ID is valid.
3464
3465ERRORS
3466--------------------------------------------------------------------------------------------
3467
3468The following error values are specifically set by this RMR
3469function. In some cases the error message of a system call is
3470propagated up, and thus this list might be incomplete.
3471
3472
3473EINVAL
3474
3475 A parameter passed was not valid.
3476
3477EACCESS
3478
3479 The user applicarion does not have the ability to
3480 establish a wormhole to the indicated target (or maybe any
3481 target).
3482
3483ECONNREFUSED
3484
3485 The connection was refused.
3486
3487
3488EXAMPLE
3489--------------------------------------------------------------------------------------------
3490
3491
3492::
3493
3494 void* rmc;
3495 rmr_whid_t wh;
3496 rmc = rmr_init( "43086", 4096, 0 ); // init context
3497 wh = rmr_wh_open( rmc, "localhost:6123" );
3498 if( !RMR_WH_CONNECTED( wh ) ) {
3499 f fprintf( stderr, "unable to connect wormhole: %s\\n",
3500 strerror( errno ) );
3501 }
3502
3503
3504
3505SEE ALSO
3506--------------------------------------------------------------------------------------------
3507
3508rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3),
3509rmr_get_rcvfd(3), rmr_payload_size(3), rmr_send_msg(3),
3510rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3),
3511rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3),
3512rmr_mk_ring(3), rmr_ring_free(3), rmr_wh_send_msg(3),
3513rmr_wh_close(3)
3514
3515
3516NAME
3517--------------------------------------------------------------------------------------------
3518
3519rmr_wh_send_msg
3520
3521SYNOPSIS
3522--------------------------------------------------------------------------------------------
3523
3524
3525::
3526
3527 #include <rmr/rmr.h>
3528 rmr_mbuf_t* rmr_wh_send_msg( void* vctx, rmr_whid_t id, rmr_mbuf_t* msg );
3529
3530
3531
3532DESCRIPTION
3533--------------------------------------------------------------------------------------------
3534
3535The rmr_wh_send_msg function accepts a message buffer from
3536the user application and attempts to send it using the
3537wormhole ID provided (id). Unlike *rmr_send_msg,* this
3538function attempts to send the message directly to a process
3539at the other end of a wormhole which was created with
3540*rmr_wh-open().* When sending message via wormholes, the
3541normal RMr routing based on message type is ignored, and the
3542caller may leave the message type unspecified in the message
3543buffer (unless it is needed by the receiving process).
3544
3545The message buffer (msg) used to send is the same format as
3546used for regular RMr send and reply to sender operations,
3547thus any buffer allocated by these means, or calls to
3548*rmr_rcv_msg()* can be passed to this function.
3549
3550Retries
3551~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3552
3553The send operations in RMr will retry *soft* send failures
3554until one of three conditions occurs:
3555
3556
3557
35581.
3559
3560 The message is sent without error
3561
3562
35632.
3564
3565 The underlying transport reports a * hard * failure
3566
3567
35683.
3569
3570 The maximum number of retry loops has been attempted
3571
3572
3573A retry loop consists of approximately 1000 send attemps **
3574without** any intervening calls to * sleep() * or * usleep().
3575* The number of retry loops defaults to 1, thus a maximum of
35761000 send attempts is performed before returning to the user
3577application. This value can be set at any point after RMr
3578initialisation using the * rmr_set_stimeout() * function
3579allowing the user application to completely disable retires
3580(set to 0), or to increase the number of retry loops.
3581
3582Transport Level Blocking
3583~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3584
3585The underlying transport mechanism used to send messages is
3586configured in *non-blocking* mode. This means that if a
3587message cannot be sent immediately the transport mechanism
3588will **not** pause with the assumption that the inability to
3589send will clear quickly (within a few milliseconds). This
3590means that when the retry loop is completely disabled (set to
35910), that the failure to accept a message for sending by the
3592underlying mechanisms (software or hardware) will be reported
3593immediately to the user application.
3594
3595It should be noted that depending on the underlying transport
3596mechanism being used, it is extremly possible that during
3597normal operations that retry conditions are very likely to
3598happen. These are completely out of RMr's control, and there
3599is nothing that RMr can do to avoid or midigate these other
3600than by allowing RMr to retry the send operation, and even
3601then it is possible (e.g. during connection reattempts), that
3602a single retry loop is not enough to guarentee a successful
3603send.
3604
3605RETURN VALUE
3606--------------------------------------------------------------------------------------------
3607
3608On success, a new message buffer, with an empty payload, is
3609returned for the application to use for the next send. The
3610state in this buffer will reflect the overall send operation
3611state and should be RMR_OK.
3612
3613If the state in the returned buffer is anything other than
3614RMR_OK, the user application may need to attempt a
3615retransmission of the message, or take other action depending
3616on the setting of errno as described below.
3617
3618In the event of extreme failure, a NULL pointer is returned.
3619In this case the value of errno might be of some use, for
3620documentation, but there will be little that the user
3621application can do other than to move on.
3622
3623ERRORS
3624--------------------------------------------------------------------------------------------
3625
3626The following values may be passed back in the *state* field
3627of the returned message buffer.
3628
3629
3630
3631RMR_ERR_WHID
3632
3633 The wormhole ID passed in was not associated with an open
3634 wormhole, or was out of range for a valid ID.
3635
3636RMR_ERR_NOWHOPEN
3637
3638 No wormholes exist, further attempt to validate the ID are
3639 skipped.
3640
3641RMR_ERR_BADARG
3642
3643 The message buffer pointer did not refer to a valid
3644 message.
3645
3646RMR_ERR_NOHDR
3647
3648 The header in the message buffer was not valid or
3649 corrupted.
3650
3651
3652The following values may be assigned to errno on failure.
3653
3654
3655INVAL
3656
3657 Parameter(s) passed to the function were not valid, or the
3658 underlying message processing environment was unable to
3659 interpret the message.
3660
3661
3662ENOKEY
3663
3664 The header information in the message buffer was invalid.
3665
3666
3667ENXIO
3668
3669 No known endpoint for the message could be found.
3670
3671
3672EMSGSIZE
3673
3674 The underlying transport refused to accept the message
3675 because of a size value issue (message was not attempted
3676 to be sent).
3677
3678
3679EFAULT
3680
3681 The message referenced by the message buffer is corrupt
3682 (NULL pointer or bad internal length).
3683
3684
3685EBADF
3686
3687 Internal RMR error; information provided to the message
3688 transport environment was not valid.
3689
3690
3691ENOTSUP
3692
3693 Sending was not supported by the underlying message
3694 transport.
3695
3696
3697EFSM
3698
3699 The device is not in a state that can accept the message.
3700
3701
3702EAGAIN
3703
3704 The device is not able to accept a message for sending.
3705 The user application should attempt to resend.
3706
3707
3708EINTR
3709
3710 The operation was interrupted by delivery of a signal
3711 before the message was sent.
3712
3713
3714ETIMEDOUT
3715
3716 The underlying message environment timed out during the
3717 send process.
3718
3719
3720ETERM
3721
3722 The underlying message environment is in a shutdown state.
3723
3724
3725EXAMPLE
3726--------------------------------------------------------------------------------------------
3727
3728The following is a simple example of how the a wormhole is
3729created (rmr_wh_open) and then how rmr_wh_send_msg function
3730is used to send messages. Some error checking is omitted for
3731clarity.
3732
3733
3734::
3735
3736 #include <rmr/rmr.h> .// system headers omitted for clarity
3737 int main() {
3738 rmr_whid_t whid = -1; // wormhole id for sending
3739 void* mrc; //msg router context
3740 int i;
3741 rmr_mbuf_t* sbuf; // send buffer
3742 int count = 0;
3743 mrc = rmr_init( "43086", RMR_MAX_RCV_BYTES, RMRFL_NONE );
3744 if( mrc == NULL ) {
3745 fprintf( stderr, "[FAIL] unable to initialise RMr environment\\n" );
3746 exit( 1 );
3747 }
3748 while( ! rmr_ready( mrc ) ) { e i// wait for routing table info
3749 sleep( 1 );
3750 }
3751 sbuf = rmr_alloc_msg( mrc, 2048 );
3752 while( 1 ) {
3753 if( whid < 0 ) {
3754 whid = rmr_wh_open( mrc, "localhost:6123" ); // open fails if endpoint refuses conn
3755 w if( RMR_WH_CONNECTED( wh ) ) {
3756 snprintf( sbuf->payload, 1024, "periodic update from sender: %d", count++ );
3757 sbuf->len = strlen( sbuf->payload );
3758 sbuf = rmr_wh_send_msg( mrc, whid, sbuf );
3759 }
3760 }
3761 sleep( 5 );
3762 }
3763 }
3764
3765
3766
3767SEE ALSO
3768--------------------------------------------------------------------------------------------
3769
3770rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
3771rmr_payload_size(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
3772rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3),
3773rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3),
3774rmr_set_stimeout(3), rmr_wh_open(3), rmr_wh_close(3)
3775