Correct bug in timeout receive 98/1198/1 1.10.1
authorE. Scott Daniels <daniels@research.att.com>
Tue, 22 Oct 2019 20:23:36 +0000 (16:23 -0400)
committerE. Scott Daniels <daniels@research.att.com>
Tue, 22 Oct 2019 20:23:36 +0000 (16:23 -0400)
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

CHANGES
CMakeLists.txt
doc/src/man/rmr_torcv_msg.3.xfm
src/rmr/nng/include/rmr_nng_private.h
src/rmr/nng/src/mt_call_nng_static.c
src/rmr/nng/src/rmr_nng.c

diff --git a/CHANGES b/CHANGES
index 6271785..aead0f9 100644 (file)
--- 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.
 
 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
 
 2019 September 27; version 1.9.0
        Python bindings added receive all queued function and corrected a unit test
 
index 8bccdd4..f38565e 100644 (file)
@@ -36,7 +36,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 "10" )
 
 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" )
 
 set( install_root "${CMAKE_INSTALL_PREFIX}" )
 set( install_inc "include/rmr" )
index b38b9ad..ffe26dc 100644 (file)
@@ -72,6 +72,12 @@ The &ital(state) field in the message buffer will be one of the following:
 &beg_dlist(.75i : ^&bold_font )
 &di(RMR_OK) The message buffer (payload) references the received data.
 
 &beg_dlist(.75i : ^&bold_font )
 &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.
 &space
 &di(RMR_ERR_TIMEOUT) The timeout expired before a complete message was received.
        All other fields in the message buffer are not valid.
index efb2daa..9753931 100644 (file)
@@ -51,7 +51,7 @@ struct endpoint {
        Epoll information needed for the rmr_torcv_msg() funciton
 */
 typedef struct epoll_stuff {
        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
        struct epoll_event epe;                                         // event definition for event to listen to
        int ep_fd;                                                                      // file des from nng
        int nng_fd;                                                                     // fd from nng
index 71106f1..7820561 100644 (file)
@@ -64,7 +64,8 @@ static inline void queue_normal( uta_ctx_t* ctx, rmr_mbuf_t* mbuf ) {
                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.
 
                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;
 */
 static void* mt_receive( void* vctx ) {
        uta_ctx_t*              ctx;
@@ -84,7 +85,7 @@ static void* mt_receive( void* vctx ) {
        while( ! ctx->shutdown ) {
                mbuf = rcv_msg( ctx, NULL );
 
        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 {
                        if( hdr->flags & HFL_CALL_MSG ) {                                       // call generated message; ignore call-id etc and queue
                                queue_normal( ctx, mbuf );
                        } else {
index 45a0e23..d9c4c06 100644 (file)
@@ -454,7 +454,12 @@ extern rmr_mbuf_t* rmr_torcv_msg( void* vctx, rmr_mbuf_t* old_msg, int ms_to ) {
                if( (eps->ep_fd = epoll_create1( 0 )) < 0 ) {
                fprintf( stderr, "[FAIL] unable to create epoll fd: %d\n", errno );
                        free( eps );
                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 );
                }
 
                eps->nng_fd = rmr_get_rcvfd( ctx );
@@ -464,7 +469,12 @@ extern rmr_mbuf_t* rmr_torcv_msg( void* vctx, rmr_mbuf_t* old_msg, int ms_to ) {
                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 );
                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;
                }
 
                ctx->eps = eps;