Merge "Correctly include license info"
authorScott Daniels <daniels@research.att.com>
Wed, 31 Jul 2019 16:51:22 +0000 (16:51 +0000)
committerGerrit Code Review <gerrit@o-ran-sc.org>
Wed, 31 Jul 2019 16:51:22 +0000 (16:51 +0000)
47 files changed:
CHANGES
CMakeLists.txt
ci/Dockerfile
ci/ci_build.ksh
ci/publish.sh [new file with mode: 0755]
doc/CMakeLists.txt
doc/src/man/retry.im [new file with mode: 0644]
doc/src/man/rmr.7.xfm
doc/src/man/rmr_alloc_msg.3.xfm
doc/src/man/rmr_bytes2meid.3.xfm
doc/src/man/rmr_bytes2payload.3.xfm
doc/src/man/rmr_bytes2xact.3.xfm
doc/src/man/rmr_call.3.xfm
doc/src/man/rmr_close.3.xfm
doc/src/man/rmr_free_msg.3.xfm
doc/src/man/rmr_get_meid.3.xfm
doc/src/man/rmr_get_rcvfd.3.xfm
doc/src/man/rmr_get_src.3.xfm
doc/src/man/rmr_get_srcip.3.xfm
doc/src/man/rmr_get_trace.3.xfm
doc/src/man/rmr_get_trlen.3.xfm
doc/src/man/rmr_init.3.xfm
doc/src/man/rmr_init_trace.3.xfm
doc/src/man/rmr_mt_call.3.xfm
doc/src/man/rmr_mt_rcv.3.xfm
doc/src/man/rmr_payload_size.3.xfm
doc/src/man/rmr_rcv_msg.3.xfm
doc/src/man/rmr_ready.3.xfm
doc/src/man/rmr_rts_msg.3.xfm
doc/src/man/rmr_send_msg.3.xfm
doc/src/man/rmr_set_stimeout.3.xfm [new file with mode: 0644]
doc/src/man/rmr_set_trace.3.xfm
doc/src/man/rmr_str2meid.3.xfm
doc/src/man/rmr_str2xact.3.xfm
doc/src/man/rmr_support.3.xfm
doc/src/man/rmr_torcv_msg.3.xfm
doc/src/man/rmr_trace_ref.3.xfm
doc/src/man/rmr_tralloc_msg.3.xfm
doc/src/man/rmr_wh_close.3.xfm
doc/src/man/rmr_wh_open.3.xfm
doc/src/man/rmr_wh_send_msg.3.xfm
doc/src/man/setup.im [new file with mode: 0644]
doc/src/markdown.im [new file with mode: 0644]
doc/src/txt.im [new file with mode: 0644]
src/bindings/rmr-python/README.md
test/app_test/Makefile
test/app_test/lsender.c [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index dc94525..622c167 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,6 @@
 
-Change Summaries
+API change summaries and fixes to the code. Doc correctsions 
+and/or changes are not mentioned here; see the commit messages.
 
 2019 July 15; Version 1.0.39
        Prevent unnecessary usleep in retry loop.
index ef4f17f..65db51c 100644 (file)
@@ -23,6 +23,8 @@
 #      -DBUILD_DOC=1           Man pages generated
 #      -DPRESERVE_PTYPE=1      Do not change the processor type when naming deb packages
 #      -DPACK_EXTERNALS=1      Include external libraries used to build in the run-time package
+#                                              (This makes some stand-alone unit testing of bindings possible, it
+#                                              is not meant to be used for production package generation.)
 #      -DSKIP_EXTERNALS=1      Do not use Nano/NNG submodules when building; uee installed packages
 #      -DMAN_PREFIX=<path>     Supply a path where man pages are installed (default: /usr/share/man)
 
@@ -31,7 +33,7 @@ cmake_minimum_required( VERSION 3.5 )
 
 set( major_version "1" )               # should be automatically populated from git tag later, but until CI process sets a tag we use this
 set( minor_version "0" )
-set( patch_level "39" )
+set( patch_level "43" )
 
 set( install_root "${CMAKE_INSTALL_PREFIX}" )
 set( install_lib "lib" )
@@ -220,6 +222,9 @@ if( NOT SKIP_EXTERNALS )
        message( "+++ installing nano/nng with: ${nano_major}.${nano_minor} | ${nng_major}.${nng_minor}" )
 else()
        if( PACK_EXTERNALS )
+               # This makes some stand-alone unit testing possible for bindings and transport layer testing;
+               # it is not meant for production packages.
+               #
                unset( SKIP_EXTERNALS  CACHE )  # must remove so as not to trap user into a never ending failure
                unset( PACK_EXTERNALS  CACHE )
                message( FATAL_ERROR "ERROR: PACK_EXTERNALS can be set only if SKIP_EXTERNALS is unset (=0, or not supplied on command line)" )
index 579adfa..0f6d871 100755 (executable)
@@ -23,6 +23,15 @@ RUN apt-get update && apt-get -q -y install cmake ksh alien
 ADD . /tmp
 WORKDIR /tmp
 
-# build RMr, run unit tests, and generate packages
+# build RMr, run unit tests, and generate packages and package lists
 RUN ksh ci/ci_build.ksh
 
+# Executing the container "as a binary" will cause the CI publish
+# script to execute.  This will take the simple package list generated
+# by the ci_build script and copy the list of packages to the target
+# directory.  The target directory is /export by default, but can be
+# overridden from the docker run command line. In either case, the 
+# assumption is that the target directory is mounted as a volume.
+#
+ENTRYPOINT [ "ci/publish.sh" ]
+
index 40aa1f5..8c3f699 100644 (file)
 #      Date:           14 June 2019
 # --------------------------------------------------------------------------------
 
-# stash a set of packages for a particular flavour ($1)
+# stash a set of packages for a particular flavour ($1). Records what was kept
+# in a yaml file for an external process to grab, and in a simple publication
+# list for our internal publish script to gobble up.
 #
 function stash_pkgs {
+       mkdir -p $target_dir/exported
+
        for pkg in deb rpm
        do
                ls .build/*.$pkg 2>/dev/null | while read f
                do
-                       cp $f $target_dir/${f##*/}
-                       echo "  - $target_dir/${f##*/}" >>$yaml_file
+                       cp $f $target_dir/exported/${f##*/}
+                       echo "  - $target_dir/exported/${f##*/}" >>$yaml_file
                done
 
        done
@@ -70,6 +74,7 @@ do
                *)      echo "$1 is not recognised"
                        echo ""
                        echo "usage: $0 [-t target-dir]"
+                       echo "   target dir defaults to /tmp and is where packages and lists are placed."
                        exit 1
                        ;;
        esac
@@ -79,8 +84,11 @@ done
 
 if [[ ! -d $target_dir ]]
 then
-       echo "[FAIL] cannot find directory: $target_dir"
-       exit 1
+       if ! -mkdir -p $target_dir
+       then
+               echo "[FAIL] cannot find or create target directory: $target_dir"
+               exit 1
+       fi
 fi
 
 if [[ ! -d ./ci ]]                                                     # verify we are in the root of the RMr repo filesystem, abort if not
diff --git a/ci/publish.sh b/ci/publish.sh
new file mode 100755 (executable)
index 0000000..bb4f804
--- /dev/null
@@ -0,0 +1,65 @@
+#!/usr/bin/env bash
+
+# -----------------------------------------------------------------------------
+#
+# Copyright (C) 2019 AT&T Intellectual Property and Nokia
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# -----------------------------------------------------------------------------
+
+#      Mnemonic:       publish
+#      Abstract:       Simple script which copies files that the build script left
+#                              for export (packages, but could be anything). This expects
+#                              that all files in /tmp/exportd are to be copied to the 
+#                              export directory /export The export directory is assumed to be
+#                              mounted from the outside world as /export, though we will use $1
+#                              as an override so this can be changed if needed.
+#
+#      Date:           30 July 2019
+#
+# -----------------------------------------------------------------------------
+
+echo "$0 starting" >&2
+argv0=${0##*/}
+
+target=${1:-/export}
+exportd=/tmp/exported          # build script dumps here
+
+if ! cd $target
+then
+       echo "$argv0: abort: cannot find or switch to: $target" >&2
+       exit 1
+fi
+
+if [[ ! -w ./ ]]
+then
+       echo "$argv0: abort: cannot write to target directory: $target"
+       exit 1
+fi
+
+if [[ ! -d $exportd ]]
+then
+       echo "$argv0: abort: unable to find the exported directory: $exportd" >&2
+       exit 1
+fi
+
+errors=0
+echo "$argv0: copy: $exportd/* --> $target" >&2
+if ! cp -v $exportd/* $target/
+then
+       errors=1
+fi
+
+echo "$argv0: finshed, $errors errors"
+exit $errors
index 27becbd..fe59f5e 100644 (file)
@@ -84,6 +84,7 @@ if( BUILD_DOC )
                rmr_mt_rcv.3
                rmr_get_srcip.3
                rmr_trace_ref.3
+               rmr_set_stimeout.3
        )
 
        # initialise lists of files we generated
@@ -92,7 +93,9 @@ if( BUILD_DOC )
 
        # for each source, build a specific command that runs tfm to generate the
        # troff output as a gzipped file. Sed is needed to remove the leading blank
-       # that tfm likes to insert even if indention is 0.
+       # that tfm likes to insert even if indention is 0. We also generate postscript
+       # markdown, plain ascii and rts output which are left in the build directory 
+       # for the developer to use as needed.
        #
        foreach( nm IN LISTS man_names )
          set( out ${CMAKE_BINARY_DIR}/${nm} )
@@ -101,7 +104,17 @@ if( BUILD_DOC )
          add_custom_command(
                        OUTPUT ${out}.gz
                        DEPENDS ${in}
-                       COMMAND bash -c "export LIB=${CMAKE_SOURCE_DIR}/doc/src; ${tfm} ${in} stdout | sed 's/^ //' | gzip >${out}.gz; ${pfm} ${in} ${out}.ps"
+                       COMMAND bash -c "export LIB=${CMAKE_SOURCE_DIR}/doc/src; \
+                               export OUTPUT_TYPE=troff; \
+                                       ${tfm} ${in} stdout | sed 's/^ //' | gzip >${out}.gz; \
+                               export OUTPUT_TYPE=rst; \
+                                       ${tfm} ${in} ${out}.rst; \
+                               export OUTPUT_TYPE=txt; \
+                                 ${tfm} ${in} ${out}.txt; \
+                               export OUTPUT_TYPE=markdown; \
+                                       ${tfm} ${in} stdout | sed 's/^ //' >${out}.md; \
+                               export OUTPUT_TYPE=postscript; \
+                                       ${pfm} ${in} ${out}.ps"
                        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
                        COMMENT "Building manpage ${out}"
                        VERBATIM
diff --git a/doc/src/man/retry.im b/doc/src/man/retry.im
new file mode 100644 (file)
index 0000000..15ce24d
--- /dev/null
@@ -0,0 +1,70 @@
+.if false
+==================================================================================
+       Copyright (c) 2019 Nokia
+       Copyright (c) 2018-2019 AT&T Intellectual Property.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================================
+.fi
+
+.if false
+       Mnemonic:       retry.im
+       Abstract:       Common text for all send operation functions. This should be imbedded by any
+                               function which will ultimately use the internal send_msg funciton which
+                               governs retries in this manner.
+       Date:           16 July 2019
+.fi
+
+&h3(Retries)
+The send operations in RMr will retry &ital(soft) send failures until one of three
+conditions occurs:
+&half_space
+&indent
+&beg_dlist( 0.3i : ^&bold_font )
+       &di(1.) The message is sent without error
+       &half_space
+
+       &di(2.) The underlying transport reports a &ital( hard ) failure
+       &half_space
+
+       &di(3.) The maximum number of retry loops has been attempted
+       &end_dlist
+&uindent
+
+&space
+A retry loop consists of approximately 1000 send attemps &bold( without) any intervening
+calls to &ital( sleep() ) or &ital( usleep(). )
+The number of retry loops defaults to 1, thus a maximum of 1000 send attempts is performed
+before returning to the user application.
+This value can be set at any point after RMr initialisation using the &ital( rmr_set_stimeout() )
+function allowing the user application to completely disable retires (set to 0), or to
+increase the number of retry loops.
+
+&h3(Transport Level Blocking)
+The underlying transport mechanism used to send messages is configured in &ital(non-blocking)
+mode.
+This means that if a message cannot be sent immediately the transport mechanism will &bold(not)
+pause with the assumption that the inability to send will clear quickly (within a few milliseconds).
+This means that when the retry loop is completely disabled (set to 0), that the failure to
+accept a message for sending by the underlying mechanisms (software or hardware) will be
+reported immediately to the user application.
+
+&space
+It should be noted that depending on the underlying transport mechanism being used, it is
+extremly possible that during normal operations that retry conditions are very likely to
+happen.
+These are completely out of RMr's control, and there is nothing that RMr can do to avoid or midigate
+these other than by allowing RMr to retry the send operation, and even then it is possible
+(e.g. during connection reattempts), that a single retry loop is not enough to guarentee a
+successful send.
+
index affdf24..1c973c6 100644 (file)
        Date            29 January 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** and rst.im will cause rst to be generated depending on OUTPUT_TYPE env
-.** var.
-.** if formatting with pfm, then pretty postscript will be generated
-
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 =
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im
 
 &line_len(6i)
 
index a9dad95..cd9da7f 100644 (file)
        Date            28 January 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im
 
 &line_len(6i)
-
 &h1(RMR Library Functions)
 &h2(NAME)
        rmr_alloc_msg
index fcc3955..0699cdf 100644 (file)
        Date            8 March 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index a8f99e2..b9412a8 100644 (file)
        Date            8 March 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index dbfe679..97fb5a3 100644 (file)
        Date            8 March 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 6be29d6..edd8a5b 100644 (file)
        Date            28 January 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
@@ -84,6 +73,9 @@ no message was received to process.
 Currently the threshold is fixed at 20 messages, though in future versions of the library
 this might be extended to be a parameter which the user application may set.
 
+.** pull in common retry text
+.im &{lib}/man/retry.im 
+
 &h2(RETURN VALUE)
 The &cw(rmr_call) function returns a pointer to a message buffer with the state set to reflect
 the overall state of call processing (see Errors below). 
@@ -175,6 +167,7 @@ rmr_rts_msg(3),
 rmr_ready(3),
 rmr_fib(3),
 rmr_has_str(3),
+rmr_set_stimeout(3),
 rmr_tokenise(3),
 rmr_mk_ring(3),
 rmr_ring_free(3)
index 8b05f0b..3fe439c 100644 (file)
        Date            21 February 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index e29f8d9..5c0fd91 100644 (file)
        Date            28 January 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 427fbd6..939a372 100644 (file)
        Date            8 March 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 8300d4e..54cc515 100644 (file)
        Date            11 February 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 42146e8..98ec5a5 100644 (file)
        Date            8 March 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 =
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 050f1f2..7db7efe 100644 (file)
        Date            11 June 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 =
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index f22596a..21c0285 100644 (file)
        Date            19 April 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 1f0d774..770935c 100644 (file)
        Date            19 April 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 
 &line_len(6i)
index 83a0f18..3871d03 100644 (file)
        Date            28 January 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 8d6b1da..b6e534b 100644 (file)
        Date            19 April 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 6cbfc24..ecb65ca 100644 (file)
        Date            24 May 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
@@ -75,7 +64,7 @@ If the ID value is not in the proper range, the attempt to make the call will fa
 &space
 Messages which are received while waiting for the response are queued on a &ital(normal)
 receive queue and will be delivered to the user application with the next invocation 
-of &itaL( rmr_mt_rcv() ) or &ital( rmr_rvv_msg().) 
+of &ital( rmr_mt_rcv() ) or &ital( rmr_rvv_msg().) 
 by RMR, and are returned to the user application when &cw(rmr_rcv_msg) is 
 invoked.
 These messages are returned in th order received, one per call to &cw(rmr_rcv_msg.)
@@ -83,7 +72,7 @@ These messages are returned in th order received, one per call to &cw(rmr_rcv_ms
 &space
 NOTE: Currently the multi-threaded functions are supported only when the NNG 
 transport mechanism is being used. It will not be possible to link a programme
-using the nanomsg version of the library when references to this function are
+using the Nanomsg version of the library when references to this function are
 present.
 
 &h3(The Transaction ID)
@@ -98,6 +87,8 @@ the return buffer has the matching transaction ID. This can be done transparentl
 the application uses the &ital( rmr_rts_msg() ) function and does not adjust the 
 transaction ID.
 
+.** pull in common retry text
+.im &{lib}/man/retry.im 
 
 &h2(RETURN VALUE)
 The &cw(rmr_mt_call) function returns a pointer to a message buffer with the state set to reflect
@@ -211,6 +202,7 @@ rmr_rts_msg(3),
 rmr_ready(3),
 rmr_fib(3),
 rmr_has_str(3),
+rmr_set_stimeout(3),
 rmr_tokenise(3),
 rmr_mk_ring(3),
 rmr_ring_free(3)
index 7c83f18..8be015a 100644 (file)
        Date            24 May 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 7dbfa69..9e8bf1c 100644 (file)
        Date            29 January 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 
 &line_len(6i)
index b432f9d..6b0c40c 100644 (file)
        Date            29 January 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 9a82010..61ea2f8 100644 (file)
        Date            28 January 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index bad1b22..a5251d4 100644 (file)
        Date            28 January 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
@@ -59,6 +48,9 @@ message type and routing table.
 Other than this small difference, the behaviour is exactly the same as
 &cw(rmr_send_msg.)
 
+.** pull in common retry text
+.im &{lib}/man/retry.im 
+
 &h2(RETURN VALUE)
 On success, a new message buffer, with an empty payload, is returned for the application
 to use for the next send.
@@ -141,6 +133,7 @@ rmr_rcv_specific(3),
 rmr_ready(3),
 rmr_fib(3),
 rmr_has_str(3),
+rmr_set_stimeout(3),
 rmr_tokenise(3),
 rmr_mk_ring(3),
 rmr_ring_free(3)
index 6497781..9d9b625 100644 (file)
        Date            28 January 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
@@ -65,6 +54,10 @@ responsible for building the routing table used by the RMR library, and not the
 responsibility of the library.)
 
 
+.** pull in common retry text
+.im &{lib}/man/retry.im 
+
+
 &h2(RETURN VALUE)
 On success, a new message buffer, with an empty payload, is returned for the application
 to use for the next send.
@@ -72,9 +65,10 @@ The state in this buffer will reflect the overall send operation state and shoul
 &cw(RMR_OK.)
 
 &space
-If the state in the returned buffer is anything other than &cw(UT_OK,) the user application 
-may need to attempt a retransmission of the message, or take other action depending on the
-setting of &cw(errno) as described below. 
+When the message cannot be successfully sent this function will return the unsent (original) 
+message buffer with the state set to indicate the reason for failure.  
+The value of &ital( errno ) may also be set to reflect a more detailed failure reason if it
+is known.
 
 &space
 In the event of extreme failure, a NULL pointer is returned. In this case the value of 
@@ -87,6 +81,11 @@ buffer.
 
 &space
 &beg_dlist(.75i : ^&bold_font )
+&di(RMR_RETRY)         The message could not be sent, but the underlying transport mechanism
+       indicates that the failure is temporary. If the send operation is tried again
+       it might be successful.
+&di(RMR_SEND_FAILED) The send operation was not successful and the underlying transport
+       mechanism indicates a permanent (hard) failure; retrying the send is not possible.
 &di(RMR_ERR_BADARG) The message buffer pointer did not refer to a valid message.
 &di(RMR_ERR_NOHDR)  The header in the message buffer was not valid or corrupted.
 &di(RMR_ERR_NOENDPT)  The message type in the message buffer did not map to a known endpoint.
diff --git a/doc/src/man/rmr_set_stimeout.3.xfm b/doc/src/man/rmr_set_stimeout.3.xfm
new file mode 100644 (file)
index 0000000..b8747d2
--- /dev/null
@@ -0,0 +1,116 @@
+.if false
+==================================================================================
+    Copyright (c) 2019 Nokia
+    Copyright (c) 2018-2019 AT&T Intellectual Property.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================================
+.fi
+.if false
+    Mnemonic   rmr_set_stimeout.xfm
+    Abstract   The manual page for the rmr_set_stimeout function.
+    Author             E. Scott Daniels
+    Date               28 January 2019
+.fi
+
+.gv e LIB lib
+.im &{lib}/man/setup.im 
+
+&line_len(6i)
+
+&h1(RMR Library Functions)
+&h2(NAME)
+    rmr_set_stimeout
+
+&h2(SYNOPSIS )
+&indent
+&ex_start
+#include <rmr/rmr.h>
+
+rmr_mbuf_t* rmr_set_stimeout( void* vctx, int rloops );
+
+&ex_end
+&uindent
+
+&h2(DESCRIPTION)
+The &cw(rmr_set_stimeout) function sets the configuration for how RMr will retry
+message send operations which complete with either a &ital( timeout )  or &ital( again )
+completion value.  (Send operations include all of the possible message send
+functions: &ital( rmr_send_msg(), rmr_call(), rmr_rts_msg() ) and &ital( rmr_wh_send_msg(). )
+The &ital( rloops ) parameter sets the maximum number of retry loops
+that will be attempted before giving up and returning the unsuccessful state to the user
+application.
+Each retry loop is approximately 1000 attempts, and RMr does &bold( not ) invoke any sleep
+function between retries in the loop; a small, 1 mu-sec, sleep is executed between loop
+sets if the &ital( rloops ) value is greater than 1.
+
+.sp
+&h3(Disabling Retries)
+By default, the send operations will execute with an &ital( rloop ) setting of 1; each send
+operation will attempt to resend the message approximately 1000 times before giving up.
+If the user application does not want to have send operations retry when the underlying
+transport mechanism indicates &ital( timeout ) or &ital( again, ) the application should
+invoke this function and pass a value of 0 (zero) for &ital( rloops. )
+With this setting, all RMr send operations will attempt a send operation only &bold( once, )
+returning immediately to the caller with the state of that single attempt.
+
+
+&h2(RETURN VALUE)
+This function returns a -1 to indicate that the &ital( rloops ) value could not be set, and
+the value &ital( RMR_OK ) to indicate success.
+
+
+&h2(ERRORS)
+Currently errno is &bold( not ) set by this function; the only cause of a failure is an
+invalid context ( .sm &ital( vctx ) .sm ) pointer.
+
+&h2(EXAMPLE)
+The following is a simple example of how the &cw(rmr_set_stimeout) function is called.
+
+&space
+&ex_start
+    #define NO_FLAGS    0
+
+    char*      port = "43086";     // port for message router listen
+    int                max_size = 4096;    // max message size for default allocations
+    void*      mr_context;         // message router context
+
+    mr_context = rmr_init( port, max_size, NO_FLAGS );
+    if( mr_context != NULL ) {
+        rmr_set_stimeout( mr_context, 0 );    // turn off retries
+    }
+
+&ex_end
+
+
+&h2(SEE ALSO )
+.ju off
+rmr_alloc_msg(3),
+rmr_call(3),
+rmr_free_msg(3),
+rmr_init(3),
+rmr_payload_size(3),
+rmr_rcv_msg(3),
+rmr_rcv_specific(3),
+rmr_rts_msg(3),
+rmr_ready(3),
+rmr_mk_ring(3),
+rmr_ring_free(3),
+rmr_send_msg(3),
+rmr_torcv_rcv(3),
+rmr_wh_send_msg(3)
+.ju on
+
+
+.qu
+
index 2ee05ba..bb9a1f4 100644 (file)
        Date            19 April 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 81ed6c9..1b741a4 100644 (file)
        Date            8 March 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 1f14cd6..6bc40d0 100644 (file)
        Date            8 March 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index b4cdd7f..29a228a 100644 (file)
        Date            28 January 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 0482419..b38b9ad 100644 (file)
        Date            29 January 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index a5db1dd..fc3e213 100644 (file)
        Date            11 July 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 64a0d72..0f26cf1 100644 (file)
        Date            19 April 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 3ee4b34..e122a28 100644 (file)
        Date            21 February 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index c271651..417a7de 100644 (file)
        Date            20 February 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
index 5a014d6..460d9cb 100644 (file)
        Date            28 January 2019
 .fi
 
-.** if formatting with tfm, the roff.im will cause roff output to be generated
-.** if formatting with pfm, then pretty postscript will be generated
 .gv e LIB lib
-.if pfm
-       .im &{lib}/generic_ps.im
-.ei
-       .gv e OUTPUT_RST use_rst
-       .if .ev &use_rst 1 = 
-               .im &{lib}/rst.im
-       .ei
-               .im &{lib}/roff.im
-       .fi
-.fi
+.im &{lib}/man/setup.im 
 
 &line_len(6i)
 
@@ -59,13 +48,15 @@ Unlike &ital(rmr_send_msg,) this function attempts to send the message directly
 to a process at the other end of a wormhole which was created with &ital(rmr_wh-open().)
 When sending message via wormholes, the normal RMr routing based on message type is
 ignored, and the caller may leave the message type unspecified in the message buffer
-(unless it is needed by the reeciving process).
+(unless it is needed by the receiving process).
 
 .sp
 The message buffer (msg) used to send is the same format as used for regular RMr 
 send and reply to sender operations, thus any buffer allocated by these means, or
 calls to &ital(rmr_rcv_msg()) can be passed to this function.
 
+.** pull in common retry text
+.im &{lib}/man/retry.im 
 
 &h2(RETURN VALUE)
 On success, a new message buffer, with an empty payload, is returned for the application
@@ -195,6 +186,7 @@ rmr_has_str(3),
 rmr_tokenise(3),
 rmr_mk_ring(3),
 rmr_ring_free(3),
+rmr_set_stimeout(3),
 rmr_wh_open(3),
 rmr_wh_close(3)
 .ju on
diff --git a/doc/src/man/setup.im b/doc/src/man/setup.im
new file mode 100644 (file)
index 0000000..546dfa1
--- /dev/null
@@ -0,0 +1,53 @@
+.if false
+==================================================================================
+       Copyright (c) 2019 Nokia
+       Copyright (c) 2018-2019 AT&T Intellectual Property.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================================
+.fi
+
+.if false
+       Mnemonic:       setup.im
+       Abstract:       Look at environment variables and pull in the correct setup prep
+                               imbed file based on the desired output type (when running tfm).
+                               Obviously, when running pfm we are always generating postscirpt
+                               so this isn't really doing much.
+       Date:           29 July 2019
+.fi
+
+
+.gv e LIB lib
+.if ! lib
+       .dv lib ..
+.fi
+
+.** CAUTION:  xfm comparisons are reverse polish so  "a b ="  is true if a == b.
+.if pfm
+       .im &{lib}/generic_ps.im
+.ei
+       .gv e OUTPUT_TYPE ot
+       .if "&ot" "txt" =
+               .im &{lib}/txt.im
+       .fi
+       .if "&ot" "rst" =
+               .im &{lib}/rst.im
+       .fi
+       .if "&ot" "markdown" =
+               .im &{lib}/markdown.im
+       .fi
+       .if "&ot" "troff" =
+               .im &{lib}/roff.im
+       .fi
+.fi
+.xx 0
diff --git a/doc/src/markdown.im b/doc/src/markdown.im
new file mode 100644 (file)
index 0000000..f31281d
--- /dev/null
@@ -0,0 +1,121 @@
+.if false
+==================================================================================
+       Copyright (c) 2019 Nokia
+       Copyright (c) 2018-2019 AT&T Intellectual Property.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================================
+.fi
+
+.if false
+       Mnemonic:       markdown.im
+       Abstract:       This is a setup for a very basic generation of markdown from the few
+                               macros which are designed for the RMR doc.  It is very scaled down from
+                               the markdown imbed file supplied with {X}fm.
+
+       Author:         E. Scott Danils
+       Date:           26 October 2016
+-------------------------------------------------------------------------------
+.fi
+
+
+.dh 1 m=.5i  e=no s=21 i=0 p=16 f=Helvetica-bold
+.dh 2  m=.5i s=21 i=0      p=14 f=Helvetica-bold
+.dh 3  m=.5i s=10 i=0      p=12 f=Helvetica-bold
+
+.ju on
+.hn off
+
+
+.** super sccript number for start_note macro
+.dv ss_num 1
+
+.**  these macros are common for prfm/tfm, markdown will override some
+.dv indent .ll -.5i .in +.25i
+.dv uindent .in -.25i .ll +.5i
+.dv smindent .ll -.2i .in +.1i
+.dv smuindent .in -.1i .ll +.2i
+
+.dv def_list .bd $1
+.dv end_dlist .ed
+.dv bd .bd $1
+.dv ed .ed
+
+.dv ex_start .sp .5 .ll -.25i .in +.25i .sf Courier .st ^&extextsize .fo off
+.** ex_end macro calls _must_ be placed in col 0 to cause an exit from no-format mode.
+.dv ex_end .fo on .sf ^&textfont .st ^&textsize .in -.25i .ll +.25i .sp .1
+
+.dv h1 .sp .1 .h1 $1
+.dv h2 .sp .1 .h2 $1
+.dv h3 .sp .1 .h3 $1
+.dv di .di $1 ^:
+
+.dv super .sm ^[ .sm ^&{ss_num}]
+.dv note .dv ss_num ^[ ^&ss_num 1 + ] ^: .sm ^[ .sm ^&{ss_num}]
+
+.dv start_note .cn start atend Times-roman 8p .5i
+.dv end_note .cn end
+.dv bold $1
+.dv cw $1
+.dv set_font_prop
+.dv ital $1
+.dv lic1 *
+.dv lic2 +
+
+.dv line_len .ll $1
+.dv space .sp 1
+.dv half_space .sp 1
+
+.** -----------------------------------------------
+.** not used, but might be needed if doc expanded
+.** .dv ta .br  ^.ta .br |
+.** .dv et .br ^.et .br
+.** .dv cl |
+.** .dv tr | .br ^.tr .br |
+.** .dv table_head $1
+.** .dv empty_cell &nbsp;
+.** -----------------------------------------------
+
+.dv break .sm ^`  ^` .br
+.dv br .sm ^`  ^` .br
+.ju off
+.dv image .ep ^[ .sm $2] ($3)
+
+.** no concept of a definition list in markdown; no start/end and just make the text bold to emulate
+.dv beg_dlist  .sp 1
+.dv bd  .sp 1
+.dv end_dlist .sp 1
+.dv ed .sp 1
+.dv di ^&break  **$1:**
+
+.dv beg_list .bl *
+.dv item .li
+.dv li .li
+.dv end_list .el
+
+.dv line .sp 1  ------
+
+.** leading indention is significant to markdown, so turn it off
+.in 0
+.dv indent
+.dv uindent .sp 2
+.dv smindent
+.dv smuindent .sp 2
+.dv bold ** .sm $1 .sm **
+.dv ital _ .sm $1 .sm _
+.dv h1 .sp 2 # $1 .br
+.dv h2 .sp 1 ## $1 .br
+.dv h3 .sp 1 ### $1 .br
+
+.dv ex_start .sp .5 .ll -4 .in .5i .sp 2 .fo off
+.dv ex_end .fo on .in 0i .ll +4 .sp 2
diff --git a/doc/src/txt.im b/doc/src/txt.im
new file mode 100644 (file)
index 0000000..bf57bf4
--- /dev/null
@@ -0,0 +1,89 @@
+.if false
+==================================================================================
+       Copyright (c) 2019 Nokia
+       Copyright (c) 2018-2019 AT&T Intellectual Property.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================================
+.fi
+
+.if false
+       Mnemonic:       txt.im
+       Abstract:       To generate raw ASCII we just need to 'disable' the macros which
+                               are defined to support things like troff, markdown and rts.
+                               For each of those macros, we just map to real {X}fm commandd
+                               which do the right thing when generating real .txt output.
+
+       Author:         E. Scott Daniels
+       Date:           29 July 2019
+
+.fi
+
+
+.cd 1 6.5i i=0
+.in .25i
+
+.** paragraph headers
+.dv h1 .h1 $1
+.dv h2 .h2 $1
+.dv h3 .h3 $1
+.dv h4 .h4 $1
+
+.dh 1 s=2,1 i=.25i
+.dh 2 s=1,1 i=.25i
+.dh 3 s=1,0 i=.25i
+.hn off
+
+.dv fig .fi t=figure
+.dv set_font_cw
+
+.dv nf  .sp 1 ^:^: .br .ll -2 .in +2
+.dv fo  .in -2 .ll +2 .sp 1
+
+.dv indent .ll -.25i .in +.25i
+.dv uindent .in -.25i .ll +.25i
+
+.dv lic1 *
+.dv lic2 +
+.dv lic3 -
+
+.dv line_len .ll $1
+.dv space .sp 1
+.dv half_space .sp 1
+.dv beg_list .sp 1 .dv lic $1 ^:
+.dv end_list .sp 1
+
+.dv beg_dlist .sp 1 .bd $1
+.dv end_dlist .ed
+
+.** for now we allow only a single layer of defitems
+.dv di .di $1 ^:
+.dv diitem  .di $1 ^:
+.dv item .li
+
+.dv ex_start .sp 1 .ll -2 .in +2 .nf
+.dv ex_end .fo on .in -2 .ll +2 .sp 1
+
+.** fonts and font macros
+.dv ital $1
+.dv bold $1
+.dv cw $1
+.dv set_font_prop
+
+.dv table .sp 1 ^[table not supported in plain txt output]  .if false
+.dv tab_cell
+.dv tab_row
+.dv end_table .fi
+
+.ju on
+
index b88d020..814c27e 100644 (file)
@@ -53,8 +53,8 @@ If rmr is *not* compiled on your system, see the below instructions for download
 See the `examples` directory.
 
 # Compiling rmr (if not already done on your system)
-(Note, you may or may not need sudo in your final command, depending on permissions to `/usr/local`. I need it)
+(Note, you may or may not need sudo in your final command, depending on permissions to `/usr/local`. The pack externals option to CMake is needed only if the NNG libary is not already installed on the system, and you do not wish to manually install it.)
 
     git clone https://gerrit.oran-osc.org/r/ric-plt/lib/rmr
     cd rmr
-    mkdir .build; cd .build; cmake ..; sudo make install
+    mkdir .build; cd .build; cmake .. -DPACK_EXTERNALS=1; sudo make install
index 67acb9f..35e3542 100644 (file)
@@ -70,6 +70,8 @@ caller: caller.c
 lcaller: lcaller.c
        gcc -I $${C_INCLUDE_PATH:-.} $< -g -o $@  -lrmr_nng -lnng -lpthread -lm
 
+lsender: lsender.c
+       gcc -I $${C_INCLUDE_PATH:-.} $< -g -o $@  -lrmr_nng -lnng -lpthread -lm
 
 
 # clean removes intermediates; nuke removes everything that can be built
diff --git a/test/app_test/lsender.c b/test/app_test/lsender.c
new file mode 100644 (file)
index 0000000..8e6bb45
--- /dev/null
@@ -0,0 +1,382 @@
+// :vim ts=4 sw=4 noet:
+/*
+==================================================================================
+       Copyright (c) 2019 Nokia
+       Copyright (c) 2018-2019 AT&T Intellectual Property.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================================
+*/
+
+/*
+       Mnemonic:       lsender.c
+       Abstract:       This is a simple sender, slimiar to sender.c, except that a timestamp
+                               is placed into the messages such that latency measurements can be 
+                               made.
+                               The message format is 'binary' defined by the lc_msg struct.
+
+                               Parms:  argv[1] == number of msgs to send (10)
+                                               argv[2] == delay                (mu-seconds, 1000000 default)
+                                               argv[3] == listen port
+
+                               Sender will send for at most 20 seconds, so if nmsgs and delay extend
+                               beyond that period the total number of messages sent will be less
+                               than n.
+
+       Date:           18 April 2019
+       Author:         E. Scott Daniels
+*/
+
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/epoll.h>
+#include <time.h>
+#include <pthread.h>
+
+
+#include <rmr/rmr.h>
+
+#define TRACE_SIZE 40          // bytes in header to provide for trace junk
+#define        SUCCESS         (-1)
+
+/*
+       Thread data
+*/
+typedef struct tdata {
+       int             id;                                     // the id we'll pass to RMr mt-call function NOT the thread id
+       int             n2send;                         // number of messages to send
+       int             delay;                          // ms delay between messages
+       void*   mrc;                            // RMr context
+       int             state;
+       int*    in_bins;                        // latency count bins
+       int*    out_bins;
+       int             nbins;                          // number of bins allocated
+       long long in_max;
+       long long out_max;
+       int             out_oor;                        // out of range count
+       int             in_oor;
+       int             in_bcount;                              // total messages tracked in bins
+       int             out_bcount;                             // total messages tracked in bins
+} tdata_t;
+
+
+/*
+       The message type placed into the payload.
+*/
+typedef struct lc_msg {
+       struct timespec out_ts;                 // time just before call executed
+       struct timespec turn_ts;                // time at the receiver,  on receipt
+       struct timespec in_ts;                  // time received back by the caller
+       int             out_retries;                    // number of retries required to send
+       int             turn_retries;                   // number of retries required to send
+} lc_msg_t;
+
+// --------------------------------------------------------------------------------
+
+
+static int sum( char* str ) {
+       int sum = 0;
+       int     i = 0;
+
+       while( *str ) {
+               sum += *(str++) + i++;
+       }
+
+       return sum % 255;
+}
+
+static void print_stats( tdata_t* td, int out, int hist ) {
+       int sum;                                        // sum of latencies
+       int csum = 0;                           // cutoff sum
+       int i95 = 0;                            // bin for the 95th count
+       int i99 = 0;                            // bin for the 99th count
+       int mean = -1;
+       int cutoff_95;                          // 95% of total messages
+       int cutoff_99;                          // 99% of total messages
+       int     oor;
+       int max;
+       int j;
+
+       if( out ) {
+               cutoff_95 = .95 * (td->out_oor + td->out_bcount);
+               cutoff_99 = .95 * (td->out_oor + td->out_bcount);
+               oor = td->out_oor;
+               max = td->out_max;
+       } else {
+               cutoff_95 = .95 * (td->in_oor + td->in_bcount);
+               cutoff_99 = .95 * (td->in_oor + td->in_bcount);
+               oor = td->in_oor;
+               max = td->in_max;
+       }
+
+       sum = 0;
+       for( j = 0; j < td->nbins; j++ ) {
+               if( csum < cutoff_95 ) {
+                       i95++;
+               }
+               if( csum < cutoff_99 ) {
+                       i99++;
+               }
+
+               if( out ) {
+                       csum += td->out_bins[j];
+                       sum += td->out_bins[j] * j;
+               } else {
+                       csum += td->in_bins[j];
+                       sum += td->in_bins[j] * j;
+               }
+       }
+
+       if( out ) {
+               if( td->out_bcount ) {
+                       mean = sum/(td->out_bcount);
+               }
+       } else {
+               if( td->in_bcount ) {
+                       mean = sum/(td->in_bcount);
+               }
+       }
+
+       if( hist ) {
+               for( j = 0; j < td->nbins; j++ ) {
+                       fprintf( stderr, "%3d %d\n", j, out ? td->out_bins[j] : td->in_bins[j] );
+               }
+       }
+
+       fprintf( stderr, "%s: oor=%d max=%.2fms  mean=%.2fms  95th=%.2fms 99th=%.2f\n", 
+               out ? "out" : " in", oor, (double)max/1000000.0, (double)mean/100.0, (double) i95/100.0, i99/100.0 );
+}
+
+/*
+       Given a message, compute the in/out and round trip latencies.
+*/
+static void compute_latency( tdata_t* td, lc_msg_t* lcm ) {
+       long long out;
+       long long turn;
+       long long in;
+       double rtl;             // round trip latency
+       double outl;    // caller to receiver latency (out)
+       double inl;             // receiver to caller latency (in)
+       int bin;
+
+       if( lcm == NULL || td == NULL ) {
+               return;
+       }
+
+       out = (lcm->out_ts.tv_sec * 1000000000) + lcm->out_ts.tv_nsec;
+       in = (lcm->in_ts.tv_sec * 1000000000) + lcm->in_ts.tv_nsec;
+       turn = (lcm->turn_ts.tv_sec * 1000000000) + lcm->turn_ts.tv_nsec;
+
+       if( in - turn > td->in_max ) {
+               td->in_max = in - turn;
+       }
+       if( turn - out > td->out_max ) {
+               td->out_max = turn-out;
+       }
+       
+       bin = (turn-out) / 10000;                       // 100ths of ms
+
+#ifdef PRINT
+       outl = ((double) turn - out) / 1000000.0;               // convert to ms
+       inl = ((double) in - turn) / 1000000.0;
+       rtl = ((double) in - out) / 1000000.0;
+
+       fprintf( stderr, "outl = %5.3fms   inl = %5.3fms  rtl = %5.3fms bin=%d\n", outl, inl, rtl, bin );
+#else
+
+       bin = (turn - out) / 10000;                     // 100ths of ms
+       if( bin < td->nbins ) {
+               td->out_bins[bin]++;
+               td->out_bcount++;
+       } else {
+               td->out_oor++;
+       }
+
+       bin = (in - turn) / 10000;                      // 100ths of ms
+       if( bin < td->nbins ) {
+               td->in_bins[bin]++;
+               td->in_bcount++;
+       } else {
+               td->in_oor++;
+       }
+
+#endif
+}
+
+/*
+       Compute the elapsed time between ts1 and ts2.
+*/
+static int elapsed( struct timespec* start_ts, struct timespec* end_ts ) {
+       long long start;
+       long long end;
+       int bin;
+
+       start = ( start_ts->tv_sec * 1000000000) + start_ts->tv_nsec;
+       end = ( end_ts->tv_sec * 1000000000) + end_ts->tv_nsec;
+
+       bin = (end - start) / 1000000;                  // ms
+
+       return bin;
+}
+
+/*
+       The main thing.
+*/
+static void* send_msgs( void* mrc, int n2send, int delay, int retry ) {
+       lc_msg_t*       lcm;                                            // pointer at the payload as a struct
+       rmr_mbuf_t*             sbuf;                                   // send buffer
+       int             count = 0;
+       int             rt_count = 0;                                   // number of messages that had a retry on first send attempt
+       int             good_count = 0;
+       int             drops = 0;
+       int             fail_count = 0;                                 // # of failure sends after first successful send
+       int             successful = 0;                                 // set to true after we have a successful send
+       char    xbuf[1024];                                             // build transaction string here
+       int             xaction_id = 1;
+       char*   tok;
+       int             state = 0;
+       struct timespec start_ts;
+       struct timespec end_ts;
+       int             mtype = 0;
+
+       if( mrc == NULL ) {
+               fprintf( stderr, "send_msg: bad mrc\n" );
+       }
+
+       sbuf = rmr_alloc_msg( mrc, 256 );       // alloc first send buffer; subsequent buffers allcoated on send
+
+       snprintf( xbuf, 200, "%31d", xaction_id );
+       while( count < n2send ) {                                                               // we send n messages after the first message is successful
+               lcm = (lc_msg_t *) sbuf->payload;
+
+               rmr_bytes2xact( sbuf, xbuf, 32 );
+
+               sbuf->mtype = 0;
+               sbuf->mtype = mtype++;                                                                                          // all go with the same type
+               if( mtype > 9 ) {
+                       mtype = 0;
+               }
+
+               sbuf->len =  sizeof( *lcm );
+               sbuf->state = RMR_OK;
+               lcm->out_retries = 0;
+               lcm->turn_retries = 0;
+               clock_gettime( CLOCK_REALTIME, &lcm->out_ts );                                  // mark time out
+               sbuf = rmr_send_msg( mrc, sbuf );
+
+               if( sbuf && sbuf->state == RMR_ERR_RETRY ) {                                    // send not accepted
+                       if( retry || count == 0  ) {
+                               rt_count++;                                                                                             // # messages that we retried beyond rmr's retry
+                       } else {
+                               if( delay ) 
+                                       usleep( delay );
+                               fail_count++;                   // send failed because we drop it
+                       }
+               }
+
+               count++;
+               if( sbuf != NULL ) {
+                       if( ! successful ) {
+                               switch( sbuf->state ) {
+                                       case RMR_OK:
+                                               clock_gettime( CLOCK_REALTIME, &start_ts );
+                                               successful = 1;
+                                               good_count++;
+                                               break;
+
+                                       default:
+                                               fprintf( stderr, "<SM> send error: rmr-state=%d ernro=%d\n", sbuf->state, errno );
+                                               sleep( 1 );
+                                               break;
+                               }
+                       } else {
+                               good_count += sbuf->state == RMR_OK;
+                       }
+               } else {
+                       sbuf = rmr_alloc_msg( mrc, 512 );                               // must have a sedn buffer at top
+                       drops++;
+               }
+
+               //if( count < n2send  &&  (count % 100) == 0  &&  delay > 0 ) {
+               if( count < n2send && delay > 0 ) {
+                       if( count % 500 ) {
+                               usleep( delay );
+                       }
+               }
+       }
+                                               
+       clock_gettime( CLOCK_REALTIME, &end_ts );
+
+       fprintf( stderr, "<SM> sending finished attempted=%d good=%d fails=%d rt=%d elapsed=%d ms, \n", count, good_count, fail_count, rt_count, elapsed( &start_ts, &end_ts ) );
+       return NULL;
+}
+
+int main( int argc, char** argv ) {
+       void* mrc;                                                      // msg router context
+       rmr_mbuf_t*     rbuf = NULL;                            // received on 'normal' flow
+       char*   listen_port = "43086";                  // largely unused here
+       long    timeout = 0;
+       int             delay = 100000;                                 // usec between send attempts
+       int             nmsgs = 10;                                             // number of messages to send
+       int             rmr_retries = 0;                                // number of retries we allow rmr to do
+
+       if( argc > 1 ) {
+               nmsgs = atoi( argv[1] );
+       }
+       if( argc > 2 ) {
+               delay = atoi( argv[2] );
+       }
+       if( argc > 4 ) {
+               listen_port = argv[4];
+       }
+       if( argc > 3 ) {
+               rmr_retries = atoi( argv[3] );
+       }
+
+       fprintf( stderr, "<LSEND> listen port: %s; sending %d messages; delay=%d\n", listen_port, nmsgs, delay );
+
+       if( (mrc = rmr_init( listen_port, 1400, RMRFL_MTCALL )) == NULL ) {             // initialise with multi-threaded call enabled
+               fprintf( stderr, "<LSEND> unable to initialise RMr\n" );
+               exit( 1 );
+       }
+
+       fprintf( stderr, "\nsetting rmr retries: %d\n", rmr_retries );
+       //if( rmr_retries != 1 ) {
+               rmr_set_stimeout( mrc, rmr_retries );
+       //}
+
+       timeout = time( NULL ) + 20;            // give rmr 20s to find the route table (shouldn't need that much)
+       while( ! rmr_ready( mrc ) ) {           // must have a route table before we can send; wait til RMr says it has one
+               fprintf( stderr, "<LSEND> waiting for rmr to show ready\n" );
+               sleep( 1 );
+
+               if( time( NULL ) > timeout ) {
+                       fprintf( stderr, "<LSEND> giving up\n" );
+                       exit( 1 );
+               }
+       }
+       fprintf( stderr, "<LSEND> rmr is ready; starting sender retries=%d\n", rmr_retries );
+
+       send_msgs( mrc, nmsgs, delay, rmr_retries );
+
+       fprintf( stderr, "pausing for drain\n" );
+       sleep( 3 );
+       fprintf( stderr, "closing down\n" );
+       rmr_close( mrc );
+
+       return 0;
+}
+