aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2024-10-20 16:25:30 -0700
committerGarrett D'Amore <garrett@damore.org>2024-10-20 16:25:30 -0700
commit5830408d11fb19aaf78cb47016ea1692e8f6d2ed (patch)
treeae761584976335bbcd84a4b80df68b5dc876c070
parentbc988244d4e3d07edd7f5ba0668744020c27f95b (diff)
downloadnng-5830408d11fb19aaf78cb47016ea1692e8f6d2ed.tar.gz
nng-5830408d11fb19aaf78cb47016ea1692e8f6d2ed.tar.bz2
nng-5830408d11fb19aaf78cb47016ea1692e8f6d2ed.zip
Synchronization primitives made a single chapter in mdbook.
-rw-r--r--docs/ref/SUMMARY.md4
-rw-r--r--docs/ref/api/thr/nng_cv.md115
-rw-r--r--docs/ref/api/thr/nng_mtx.md63
3 files changed, 2 insertions, 180 deletions
diff --git a/docs/ref/SUMMARY.md b/docs/ref/SUMMARY.md
index ba749667..91aa9601 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 29a149a0..00000000
--- a/docs/ref/api/thr/nng_cv.md
+++ /dev/null
@@ -1,115 +0,0 @@
-# nng_cv
-
-## NAME
-
-nng_cv --- condition variable
-
-## SYNOPSIS
-
-```c
-#include <nng/nng.h>
-
-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 02735423..00000000
--- 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 <nng/nng.h>
-
-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.