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
-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
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( install_root "${CMAKE_INSTALL_PREFIX}" )
set( install_inc "include/rmr" )
set( install_root "${CMAKE_INSTALL_PREFIX}" )
set( install_inc "include/rmr" )
&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.
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
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;
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 {
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 );
+ 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 );
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 );
+ ctx->eps = NULL;
+ if( old_msg != NULL ) {
+ old_msg->state = RMR_ERR_INITFAILED;
+ old_msg->tp_state = errno;
+ }
+ return old_msg;