From 5830408d11fb19aaf78cb47016ea1692e8f6d2ed Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Sun, 20 Oct 2024 16:25:30 -0700 Subject: [PATCH] Synchronization primitives made a single chapter in mdbook. --- docs/ref/SUMMARY.md | 4 +- docs/ref/api/thr/nng_cv.md | 115 ------------------------------------ docs/ref/api/thr/nng_mtx.md | 63 -------------------- 3 files changed, 2 insertions(+), 180 deletions(-) delete mode 100644 docs/ref/api/thr/nng_cv.md delete mode 100644 docs/ref/api/thr/nng_mtx.md diff --git a/docs/ref/SUMMARY.md b/docs/ref/SUMMARY.md index ba7496672..91aa9601e 100644 --- a/docs/ref/SUMMARY.md +++ b/docs/ref/SUMMARY.md @@ -18,10 +18,10 @@ - [nng_aio](./api/aio/nng_aio.md) - [aio_cancel](./api/aio/aio_cancel.md) + - [Synchronization Primitves](./api/synch.md) + - [Threading and Synchronization](./api/thr/index.md) - - [nng_cv](./api/thr/nng_cv.md) - - [nng_mtx](./api/thr/nng_mtx.md) - [nng_thread](./api/thr/nng_thread.md) - [Logging](./api/logging.md) diff --git a/docs/ref/api/thr/nng_cv.md b/docs/ref/api/thr/nng_cv.md deleted file mode 100644 index 29a149a0e..000000000 --- a/docs/ref/api/thr/nng_cv.md +++ /dev/null @@ -1,115 +0,0 @@ -# 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 deleted file mode 100644 index 027354238..000000000 --- a/docs/ref/api/thr/nng_mtx.md +++ /dev/null @@ -1,63 +0,0 @@ -# nng_mutex - -## NAME - -nng_mutex --- mutual exclusion lock - -## SYNOPSIS - -```c -#include - -typedef struct nng_mtx nng_mtx; - -int nng_mtx_alloc(nng_mtx **mtxp); -void nng_mtx_free(nng_mtx *mtx); -void nng_mtx_lock(nng_mtx *mtx); -void nng_mtx_unlock(nng_mtx *mtx); -``` - -## DESCRIPTION - -The {{i:`nng_mtx`}}{{hi:mutex}} structure provides a {{i:mutual-exclusion}} {{i:lock}}, such -that only one thread at a time can have the lock (taken using `nng_mtx_lock`). -This is critical for solving certain problems that arise in concurrent programming. - -### Initialization and Teardown - -The `nng_mtx` structure is created dynamically, by the application using {{i:`nng_mtx_alloc`}}. -This function will store a pointer to the allocate mutex at the location signified by _mtxp_. - -When the application has no further need of the mutex, it can deallocate the resources -associated using the {{i:`nng_mtx_free`}} function. - -### Locking and Unlocking - -The `nng_mtx` lock can be acquired by a calling thread using the {{i:`nng_mtx_lock`}} function. - -The caller will block until the lock is acquired. -If multiple threads are contending for ownership of the lock, the order of -acquisition is not specified, and applications must not depend on it. - -> [!NOTE] -> Mutex locks are _not_ recursive; attempts to reacquire the -> same mutex may result in deadlock or aborting the current program. -> It is a programming error for the owner of a mutex to attempt to -> reacquire it. - -The lock can be released by the thread that has ownership using the {{i:`nng_mtx_unlock`}} function. - -> [!NOTE] -> A mutex can _only_ be unlocked by the thread that locked it. -> Attempting to unlock a mutex that is not owned by the caller will result -> in undefined behavior. - -## RETURN VALUES - -The `nng_mtx_lock` function returns 0 on success, or non-zero on failure. - -The other mutex functions always succeed, and have no return values. - -## ERRORS - -- `NNG_ENOMEM`: Insufficient memory is available, or the table is full.