From 7d1b7b0de82414ad25ebd323b2913de72ab448c1 Mon Sep 17 00:00:00 2001 From: "E. Scott Daniels" Date: Tue, 22 Oct 2019 16:23:36 -0400 Subject: [PATCH] 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 Change-Id: I259a5e5a0a18e53ffb03cc4c47d171e77e998835 --- CHANGES | 11 +++++++++-- CMakeLists.txt | 2 +- doc/src/man/rmr_torcv_msg.3.xfm | 6 ++++++ src/rmr/nng/include/rmr_nng_private.h | 2 +- src/rmr/nng/src/mt_call_nng_static.c | 5 +++-- src/rmr/nng/src/rmr_nng.c | 14 ++++++++++++-- 6 files changed, 32 insertions(+), 8 deletions(-) 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 @@ 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( 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 @@ -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. +&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 @@ struct endpoint { 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 @@ 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. - 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 @@ static void* mt_receive( void* vctx ) { 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 @@ 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 ); - 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 @@ 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 ); - 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; -- 2.16.6