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;