Correct bug in timeout receive

It was possible for the timeout receive function to return a
nil message buffer pointer, even if the calling function passed
a pointer in for reuse.  The exposure was limited only to when
the epoll environment could not be initialised which we believe
has never been observed.

Signed-off-by: E. Scott Daniels <daniels@research.att.com>
Change-Id: I259a5e5a0a18e53ffb03cc4c47d171e77e998835
diff --git a/CHANGES b/CHANGES
index 6271785..aead0f9 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,7 +1,14 @@
-pic2
-API and build change  and fixe summaries. Doc correctsions
+
+API and build change  and fix summaries. Doc correctsions
 and/or changes are not mentioned here; see the commit messages.
 
+2019 October 21; version 1.10.1
+	Fix to prevent null message buffer from being returned by the timeout
+	receive function if the function is passed one to reuse.
+
+2019 October 21; version 1.10.1
+	Add periodic dump of send count info to stderr.
+
 2019 September 27; version 1.9.0
 	Python bindings added receive all queued function and corrected a unit test
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8bccdd4..f38565e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,7 +36,7 @@
 
 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 "10" )
-set( patch_level "0" )
+set( patch_level "1" )
 
 set( install_root "${CMAKE_INSTALL_PREFIX}" )
 set( install_inc "include/rmr" )
diff --git a/doc/src/man/rmr_torcv_msg.3.xfm b/doc/src/man/rmr_torcv_msg.3.xfm
index b38b9ad..ffe26dc 100644
--- a/doc/src/man/rmr_torcv_msg.3.xfm
+++ b/doc/src/man/rmr_torcv_msg.3.xfm
@@ -73,6 +73,12 @@
 &di(RMR_OK) The message buffer (payload) references the received data.
 
 &space
+&di(RMR_ERR_INITFAILED) The first call to this function must initialise an underlying
+	system notification mechanism. On failure, this error is returned and errno
+	will have the system error status set.  If this function fails to intialise,
+	the poll mechansim, it is likely that message receives will never be successful.
+
+&space
 &di(RMR_ERR_TIMEOUT) The timeout expired before a complete message was received.
 	All other fields in the message buffer are not valid.
 
diff --git a/src/rmr/nng/include/rmr_nng_private.h b/src/rmr/nng/include/rmr_nng_private.h
index efb2daa..9753931 100644
--- a/src/rmr/nng/include/rmr_nng_private.h
+++ b/src/rmr/nng/include/rmr_nng_private.h
@@ -51,7 +51,7 @@
 	Epoll information needed for the rmr_torcv_msg() funciton
 */
 typedef struct epoll_stuff {
-	struct epoll_event events[1];				// wait on 10 possible events
+	struct epoll_event events[1];				// wait on 1 possible events
 	struct epoll_event epe;						// event definition for event to listen to
 	int ep_fd;									// file des from nng
 	int nng_fd;									// fd from nng
diff --git a/src/rmr/nng/src/mt_call_nng_static.c b/src/rmr/nng/src/mt_call_nng_static.c
index 71106f1..7820561 100644
--- a/src/rmr/nng/src/mt_call_nng_static.c
+++ b/src/rmr/nng/src/mt_call_nng_static.c
@@ -64,7 +64,8 @@
 		The transaction ID in the message matches the expected ID in the chute,
 		then the message is given to the chute and the chute's semaphore is tickled.
 
-		If none are true, the message is dropped.
+		If none are true, the message is queued on the normal receive queue and that
+		related semaphore is tickeled.
 */
 static void* mt_receive( void* vctx ) {
 	uta_ctx_t*		ctx;
@@ -84,7 +85,7 @@
 	while( ! ctx->shutdown ) {
 		mbuf = rcv_msg( ctx, NULL );
 
-		if( mbuf != NULL && (hdr = (uta_mhdr_t *) mbuf->header) != NULL ) {
+		if( mbuf != NULL && (hdr = (uta_mhdr_t *) mbuf->header) != NULL && mbuf->payload != NULL ) {
 			if( hdr->flags & HFL_CALL_MSG ) {					// call generated message; ignore call-id etc and queue
 				queue_normal( ctx, mbuf );
 			} else {
diff --git a/src/rmr/nng/src/rmr_nng.c b/src/rmr/nng/src/rmr_nng.c
index 45a0e23..d9c4c06 100644
--- a/src/rmr/nng/src/rmr_nng.c
+++ b/src/rmr/nng/src/rmr_nng.c
@@ -454,7 +454,12 @@
 		if( (eps->ep_fd = epoll_create1( 0 )) < 0 ) {
 	    	fprintf( stderr, "[FAIL] unable to create epoll fd: %d\n", errno );
 			free( eps );
-			return NULL;
+			ctx->eps = NULL;
+			if( old_msg != NULL ) {
+				old_msg->state = RMR_ERR_INITFAILED;
+				old_msg->tp_state = errno;
+			}
+			return old_msg;
 		}
 
 		eps->nng_fd = rmr_get_rcvfd( ctx );
@@ -464,7 +469,12 @@
 		if( epoll_ctl( eps->ep_fd, EPOLL_CTL_ADD, eps->nng_fd, &eps->epe ) != 0 )  {
 	    	fprintf( stderr, "[FAIL] epoll_ctl status not 0 : %s\n", strerror( errno ) );
 			free( eps );
-			return NULL;
+			ctx->eps = NULL;
+			if( old_msg != NULL ) {
+				old_msg->state = RMR_ERR_INITFAILED;
+				old_msg->tp_state = errno;
+			}
+			return old_msg;
 		}
 
 		ctx->eps = eps;