From a9633313ec8e578c805cd53b37ba3360d83157bc Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Tue, 15 Aug 2017 21:59:55 -0700 Subject: Provide versions of mutex, condvar, and aio init that never fail. If the underlying platform fails (FreeBSD is the only one I'm aware of that does this!), we use a global lock or condition variable instead. This means that our lock initializers never ever fail. Probably we could eliminate most of this for Linux and Darwin, since on those platforms, mutex and condvar initialization reasonably never fails. Initial benchmarks show little difference either way -- so we can revisit (optimize) later. This removes a lot of otherwise untested code in error cases and so forth, improving coverage and resilience in the face of allocation failures. Platforms other than POSIX should follow a similar pattern if they need this. (VxWorks, I'm thinking of you.) Most sane platforms won't have an issue here, since normally these initializations do not need to allocate memory. (Reportedly, even FreeBSD has plans to "fix" this in libthr2.) While here, some bugs were fixed in initialization & teardown. The fallback code is properly tested with dedicated test cases. --- src/core/platform.h | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'src/core/platform.h') diff --git a/src/core/platform.h b/src/core/platform.h index 7acf16ef..f6f0b974 100644 --- a/src/core/platform.h +++ b/src/core/platform.h @@ -85,10 +85,9 @@ typedef struct nni_plat_thr nni_plat_thr; // Threading & Synchronization Support // -// nni_plat_mtx_init initializes a mutex structure. This may require dynamic -// allocation, depending on the platform. It can return NNG_ENOMEM if that -// fails. An initialized mutex must be distinguishable from zeroed memory. -extern int nni_plat_mtx_init(nni_plat_mtx *); +// nni_plat_mtx_init initializes a mutex structure. An initialized mutex must +// be distinguishable from zeroed memory. +extern void nni_plat_mtx_init(nni_plat_mtx *); // nni_plat_mtx_fini destroys the mutex and releases any resources allocated // for it's use. If the mutex is zeroed memory, this should do nothing. @@ -99,20 +98,14 @@ extern void nni_plat_mtx_fini(nni_plat_mtx *); extern void nni_plat_mtx_lock(nni_plat_mtx *); // nni_plat_mtx_unlock unlocks the mutex. This can only be performed by the -// threadthat owned the mutex. +// thread that owned the mutex. extern void nni_plat_mtx_unlock(nni_plat_mtx *); -// nni_plat_mtx_tryenter tries to lock the mutex. If it can't, it may return -// NNG_EBUSY if the mutex is already owned. -extern int nni_plat_mtx_trylock(nni_plat_mtx *); - // nni_plat_cv_init initializes a condition variable. We require a mutex be // supplied with it, and that mutex must always be held when performing any -// operations on the condition variable (other than fini.) This may require -// dynamic allocation, and if so this operation may fail with NNG_ENOMEM. -// As with mutexes, an initialized mutex should be distinguishable from -// zeroed memory. -extern int nni_plat_cv_init(nni_plat_cv *, nni_plat_mtx *); +// operations on the condition variable (other than fini.) As with mutexes, an +// initialized mutex should be distinguishable from zeroed memory. +extern void nni_plat_cv_init(nni_plat_cv *, nni_plat_mtx *); // nni_plat_cv_fini releases all resources associated with condition variable. // If the cv points to just zeroed memory (was never initialized), it does -- cgit v1.2.3-70-g09d2