From d82509e810aea45454f9b3692c5577bd86cd65c7 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Fri, 11 Oct 2024 17:25:42 -0700 Subject: Converted condition variable docs to mdbook. This also is implemented using a single unified manual page that should be easier to reference. --- docs/ref/api/thr/index.md | 1 + docs/ref/api/thr/nng_cv.md | 115 ++++++++++++++++++++++++++++++++++++++++++++ docs/ref/api/thr/nng_mtx.md | 2 +- 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 docs/ref/api/thr/nng_cv.md (limited to 'docs/ref/api') diff --git a/docs/ref/api/thr/index.md b/docs/ref/api/thr/index.md index d9d168ac..6355cfef 100644 --- a/docs/ref/api/thr/index.md +++ b/docs/ref/api/thr/index.md @@ -1,3 +1,4 @@ # Threading Functions +- [nng_cv](nng_cv.md) - [nng_mtx](nng_mtx.md) diff --git a/docs/ref/api/thr/nng_cv.md b/docs/ref/api/thr/nng_cv.md new file mode 100644 index 00000000..29a149a0 --- /dev/null +++ b/docs/ref/api/thr/nng_cv.md @@ -0,0 +1,115 @@ +# nng_cv + +## NAME + +nng_cv --- condition variable + +## SYNOPSIS + +```c +#include + +typedef struct nng_cv nng_cv; + +int nng_cv_alloc(nng_cv **cvp, nng_mtx *mtx); +void nng_cv_free(nng_cv *cv); +int nng_cv_until(nng_cv *cv, nng_time when); +void nng_cv_wait(nng_cv *cv); +void nng_cv_wake(nng_cv *cv); +void nng_cv_wake1(nng_cv *cv); +``` + +## DESCRIPTION + +The {{i:`nng_cv`}} structure implements a {{i:condition variable}}, associated with the +the [mutex][nng_mtx] _mtx_ which was supplied when it was created. + +Condition variables provide for a way to wait on an arbitrary condition, and to be woken +when the condition is signaled. +The mutex is dropped while the caller is asleep, and reacquired atomically when the caller +is woken. + +> [!IMPORTANT] +> +> The caller of `nng_cv_until`, `nng_cv_wait`, `nng_cv_wake`, and `nng_cv_wake1` _must_ +> have ownership of the mutex _mtx_ when calling these functions. + +### Initialization and Teardown + +The {{i:`nng_cv_alloc`}} function allocates a condition variable, and associated with the mutex _mtx_, +and returns a pointer to it in _cvp_. +The {{i:`nng_cv_free`}} function deallocates the condition variable _cv_. + +### Waiting for the Condition + +The {{i:`nng_cv_until`}} and {{i:`nng_cv_wait`}} functions put the caller to sleep until the condition +variable _cv_ is signaled, or (in the case of `nng_cv_until`), the specified time _when_ +(as determined by [`nng_clock`][nng_clock] is reached. + +While `nng_cv_wait` never fails and so has no return value, the `nng_cv_until` function can +return `NNG_ETIMEDOUT` if the time is reached before condition _cv_ is signaled by +either `nng_cv_wake` or `nng_cv_wake1`. + +### Signaling the Condition + +The {{i:`nng_cv_wake`}} and {{i:`nng_cv_wake1`}} functions wake threads waiting in +`nng_cv_until` or `nng_cv_wake`. The difference between these functions is that +`nng_cv_wake` will wake _every_ thread, whereas `nng_cv_wake1` will wake up exactly +one thread (which may be chosen randomly). + +> [!TIP] +> Use of `nng_cv_wake1` may be used to reduce the "thundering herd" syndrom of waking +> all threads concurrently, but should only be used in circumstances where the application +> does not depend on _which_ thread will be woken. When in doubt, `nng_cv_wake` is safer. + +## EXAMPLE + +### Example 1: Allocating the condition variable + +```c + nng_mtx *m; + nng_cv *cv; + nng_mtx_alloc(&m); // error checks elided + nng_cv_alloc(&cv, m); +``` + +### Example 2: Waiting for the condition + +```c + expire = nng_clock() + 1000; // 1 second in the future + nng_mtx_lock(m); // assume cv was allocated using m + while (!condition_true) { + if (nng_cv_until(cv, expire) == NNG_ETIMEDOUT) { + printf("Time out reached!\n"); + break; + } + } + // condition_true is true + nng_mtx_unlock(m); +``` + +### Example 3: Signaling the condition + +```c + nng_mtx_lock(m); + condition_true = true; + nng_cv_wake(cv); + nng_mtx_unlock(m); +``` + +## RETURN VALUES + +This function returns 0 on success, and non-zero otherwise. + +## ERRORS + +- `NNG_ENOMEM`: Insufficient free memory exists. +- `NNG_ETIMEDOUT`: The time specified by _when_ is reached without the condition being signaled. + +## SEE ALSO + +[nng_clock][nng_clock], +[nng_mtx][nng_mtx] + +[nng_clock]: ../util/nng_clock.md +[nng_mtx]: ../thr/nng_mtx.md diff --git a/docs/ref/api/thr/nng_mtx.md b/docs/ref/api/thr/nng_mtx.md index 37249e4f..02735423 100644 --- a/docs/ref/api/thr/nng_mtx.md +++ b/docs/ref/api/thr/nng_mtx.md @@ -1,4 +1,4 @@ -# nng_id_map +# nng_mutex ## NAME -- cgit v1.2.3-70-g09d2