From 5902d02ad0a056a146231568f1293ffbcd59f61c Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Wed, 18 Apr 2018 20:38:00 -0700 Subject: fixes #346 nng_recv() sometimes acts on null `msg` pointer This closes a fundamental flaw in the way aio structures were handled. In paticular, aio expiration could race ahead, and fire before the aio was properly registered by the provider. This ultimately led to the possibility of duplicate completions on the same aio. The solution involved breaking up nni_aio_start into two functions. nni_aio_begin (which can be run outside of external locks) simply validates that nni_aio_fini() has not been called, and clears certain fields in the aio to make it ready for use by the provider. nni_aio_schedule does the work to register the aio with the expiration thread, and should only be called when the aio is actually scheduled for asynchronous completion. nni_aio_schedule_verify does the same thing, but returns NNG_ETIMEDOUT if the aio has a zero length timeout. This change has a small negative performance impact. We have plans to rectify that by converting nni_aio_begin to use a locklesss flag for the aio->a_fini bit. While we were here, we fixed some error paths in the POSIX subsystem, which would have returned incorrect error codes, and we made some optmizations in the message queues to reduce conditionals while holding locks in the hot code path. --- src/core/msgqueue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/msgqueue.h') diff --git a/src/core/msgqueue.h b/src/core/msgqueue.h index 2d23f448..2f1a46eb 100644 --- a/src/core/msgqueue.h +++ b/src/core/msgqueue.h @@ -63,7 +63,7 @@ extern void nni_msgq_set_get_error(nni_msgq *, int); // What this does is treat the message queue condition as if it were // successful, returning 0, and discarding the message. If zero is // passed then this mode is reset to normal. -extern void nni_msgq_set_best_effort(nni_msgq *, int); +extern void nni_msgq_set_best_effort(nni_msgq *, bool); // nni_msgq_filter is a callback function used to filter messages. // The function is called on entry (put) or exit (get). The void -- cgit v1.2.3-70-g09d2