summaryrefslogtreecommitdiff
path: root/docs/ref
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2024-04-05 08:07:57 -0700
committerGarrett D'Amore <garrett@damore.org>2024-04-05 08:07:57 -0700
commit4d178a9eb65b973d18c80afa328a070ee09fd768 (patch)
treef6e35799565ec25d19629a2a67d8adec3ead7b68 /docs/ref
parent05beb9ed7d75142483e3963501898fd9f32d7508 (diff)
downloadnng-4d178a9eb65b973d18c80afa328a070ee09fd768.tar.gz
nng-4d178a9eb65b973d18c80afa328a070ee09fd768.tar.bz2
nng-4d178a9eb65b973d18c80afa328a070ee09fd768.zip
Refactor thread related pages.
Diffstat (limited to 'docs/ref')
-rw-r--r--docs/ref/thr/nng_cv_alloc.adoc39
-rw-r--r--docs/ref/thr/nng_cv_free.adoc20
-rw-r--r--docs/ref/thr/nng_cv_until.adoc55
-rw-r--r--docs/ref/thr/nng_cv_wait.adoc53
-rw-r--r--docs/ref/thr/nng_cv_wake.adoc48
-rw-r--r--docs/ref/thr/nng_cv_wake1.adoc48
-rw-r--r--docs/ref/thr/nng_mtx_alloc.adoc40
-rw-r--r--docs/ref/thr/nng_mtx_free.adoc21
-rw-r--r--docs/ref/thr/nng_mtx_lock.adoc34
-rw-r--r--docs/ref/thr/nng_mtx_unlock.adoc24
-rw-r--r--docs/ref/thr/nng_thread_create.adoc56
-rw-r--r--docs/ref/thr/nng_thread_destroy.adoc23
-rw-r--r--docs/ref/thr/nng_thread_set_name.adoc27
13 files changed, 488 insertions, 0 deletions
diff --git a/docs/ref/thr/nng_cv_alloc.adoc b/docs/ref/thr/nng_cv_alloc.adoc
new file mode 100644
index 00000000..cd0d5975
--- /dev/null
+++ b/docs/ref/thr/nng_cv_alloc.adoc
@@ -0,0 +1,39 @@
+## nng_cv_alloc
+
+Allocate condition variable.
+
+### Synopsis
+
+```c
+#include <nng/nng.h>
+#include <nng/supplemental/util/platform.h>
+
+typedef struct nng_cv nng_cv;
+
+int nng_cv_alloc(nng_cv **cvp, nng_mtx *mtx);
+```
+
+### Description
+
+The `nng_cv_alloc` function allocates a condition variable, using the mutex _mtx_, and returns it in _cvp_.
+
+Every condition variable is associated with a mutex, which must be owned when a thread waits for the condition using xref:nng_cv_wait.adoc[`nng_cv_wait`] or xref:nng_cv_until.adoc[`nng_cv_until`].
+The mutex must also be owned when signaling the condition using the xref:nng_cv_wake.adoc[`nng_cv_wake`] or xref:nng_cv_wake1.adoc[`nng_cv_wake1`] functions.
+
+### Return Values
+
+This function returns 0 on success, and non-zero otherwise.
+
+### Errors
+
+[horizontal]
+`NNG_ENOMEM`:: Insufficient free memory exists.
+
+### See Also
+
+xref:nng_cv_free.adoc[nng_cv_free],
+xref:nng_cv_until.adoc[nng_cv_until],
+xref:nng_cv_wait.adoc[nng_cv_wait],
+xref:nng_cv_wake.adoc[nng_cv_wake],
+xref:nng_cv_wake1.adoc[nng_cv_wake1],
+xref:nng_mtx_alloc.adoc[nng_mtx_alloc]
diff --git a/docs/ref/thr/nng_cv_free.adoc b/docs/ref/thr/nng_cv_free.adoc
new file mode 100644
index 00000000..7d691040
--- /dev/null
+++ b/docs/ref/thr/nng_cv_free.adoc
@@ -0,0 +1,20 @@
+## nng_cv_free
+
+Free condition variable.
+
+### Synopsis
+
+```c
+#include <nng/nng.h>
+#include <nng/supplemental/util/platform.h>
+
+void nng_cv_free(nng_cv *cv);
+```
+
+### Description
+
+The `nng_cv_free` function frees the condition variable _cv_.
+
+### See Also
+
+xref:nng_cv_alloc.adoc[nng_cv_alloc]
diff --git a/docs/ref/thr/nng_cv_until.adoc b/docs/ref/thr/nng_cv_until.adoc
new file mode 100644
index 00000000..a24aacf1
--- /dev/null
+++ b/docs/ref/thr/nng_cv_until.adoc
@@ -0,0 +1,55 @@
+## nng_cv_until
+
+Wait for condition or timeout.
+
+### Synopsis
+
+```c
+#include <nng/nng.h>
+#include <nng/supplemental/util/platform.h>
+
+int nng_cv_until(nng_cv *cv, nng_time when);
+```
+
+### Description
+
+The `nng_cv_until` function waits until either the condition variable _cv_ is signaled by another thread calling either xref:nng_cv_wake.adoc[`nng_cv_wake`] or xref:nng_cv_wake1.adoc[`nng_cv_wake1`], or the system clock (as tracked by xref:nng_clock.adoc[`nng_clock`]) reaches _when_.
+
+The caller must have have ownership of the mutex that was used when _cv_ was allocated.
+This function will drop the ownership of that mutex, and reacquire it atomically just before returning to the caller.
+
+NOTE: Any condition may be used or checked, but the condition must be checked, as it is possible for this function to wake up spuriously.
+The idiomatic way to do this is inside a loop that repeats until the condition is true.
+
+### Example
+
+The following example demonstrates use of this function:
+
+.Example 1: 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 2: Signaling the condition
+```c
+ nng_mtx_lock(m);
+ condition_true = true;
+ nng_cv_wake(cv);
+ nng_mtx_unlock(m);
+```
+
+### See Also
+
+xref:nng_cv_wait.adoc[nng_cv_wait],
+xref:nng_cv_wake.adoc[nng_cv_wake],
+xref:nng_cv_wake1.adoc[nng_cv_wake1],
+xref:nng_mtx_lock.adoc[nng_mtx_lock]
diff --git a/docs/ref/thr/nng_cv_wait.adoc b/docs/ref/thr/nng_cv_wait.adoc
new file mode 100644
index 00000000..0fedf867
--- /dev/null
+++ b/docs/ref/thr/nng_cv_wait.adoc
@@ -0,0 +1,53 @@
+## nng_cv_wait
+
+Wait for condition.
+
+### Synopsis
+
+```c
+#include <nng/nng.h>
+#include <nng/supplemental/util/platform.h>
+
+void nng_cv_wait(nng_cv *cv);
+```
+
+### Description
+
+The `nng_cv_wait` waits for the condition variable _cv_ to be signaled
+by another thread calling either xref:nng_cv_wake.adoc[`nng_cv_wake`] or
+xref:nng_cv_wake1.adoc[`nng_cv_wake1`].
+
+The caller must have have ownership of the mutex that was used when _cv_ was allocated.
+This function will drop the ownership of that mutex, and reacquire it atomically just before returning to the caller.
+
+NOTE: Any condition may be used or checked, but the condition must be checked, as it is possible for this function to wake up spuriously.
+The idiomatic way to do this is inside a loop that repeats until the condition is true.
+
+### Example
+
+The following example demonstrates use of this function:
+
+.Example 1: Waiting for the condition
+```c
+ nng_mtx_lock(m); // assume cv was allocated using m
+ while (!condition_true) {
+ nng_cv_wait(cv);
+ }
+ // condition_true is true
+ nng_mtx_unlock(m);
+```
+
+.Example 2: Signaling the condition
+```c
+ nng_mtx_lock(m);
+ condition_true = true;
+ nng_cv_wake(cv);
+ nng_mtx_unlock(m);
+```
+
+### See Also
+
+xref:nng_cv_until.adoc[nng_cv_until],
+xref:nng_cv_wake.adoc[nng_cv_wake],
+xref:nng_cv_wake1.adoc[nng_cv_wake1],
+xref:nng_mtx_lock.adoc[nng_mtx_lock]
diff --git a/docs/ref/thr/nng_cv_wake.adoc b/docs/ref/thr/nng_cv_wake.adoc
new file mode 100644
index 00000000..717b2ca9
--- /dev/null
+++ b/docs/ref/thr/nng_cv_wake.adoc
@@ -0,0 +1,48 @@
+## nng_cv_wake
+
+Wake all waiters.
+
+### Synopsis
+
+```c
+#include <nng/nng.h>
+#include <nng/supplemental/util/platform.h>
+
+void nng_cv_wake(nng_cv *cv);
+```
+
+### Description
+
+The `nng_cv_wake` wakes any threads waiting for the condition variable _cv_
+to be signaled in the xref:nng_cv_wait.adoc[`nng_cv_wait`] or
+xref:nng_cv_until.adoc[`nng_cv_until`] functions.
+
+The caller must have have ownership of the mutex that was used when
+_cv_ was allocated.
+
+NOTE: The caller should already have set the condition that the waiters
+will check, while holding the mutex.
+
+TIP: This function wakes all threads, which is generally safer but can
+lead to a performance problem when there are many waiters, as they are all
+woken simultaneously and may contend for resources.
+See xref:nng_cv_wake1.adoc[`nng_cv_wake1`] for a solution to this problem.
+
+### Return Values
+
+None.
+
+### Errors
+
+None.
+
+### See Also
+
+xref:nng_cv_alloc.adoc[nng_cv_alloc],
+xref:nng_cv_until.adoc[nng_cv_until],
+xref:nng_cv_wait.adoc[nng_cv_wait],
+xref:nng_cv_wake1.adoc[nng_cv_wake1],
+xref:nng_mtx_alloc.adoc[nng_mtx_alloc],
+xref:nng_mtx_lock.adoc[nng_mtx_lock],
+xref:nng_mtx_unlock.adoc[nng_mtx_unlock],
+xref:nng.adoc[nng]
diff --git a/docs/ref/thr/nng_cv_wake1.adoc b/docs/ref/thr/nng_cv_wake1.adoc
new file mode 100644
index 00000000..d9d3edd4
--- /dev/null
+++ b/docs/ref/thr/nng_cv_wake1.adoc
@@ -0,0 +1,48 @@
+## nng_cv_wake1
+
+Wake one waiter.
+
+### Synopsis
+
+```c
+#include <nng/nng.h>
+#include <nng/supplemental/util/platform.h>
+
+void nng_cv_wake1(nng_cv *cv);
+```
+
+### Description
+
+The `nng_cv_wake1` wakes at most one thread waiting for the condition
+variable _cv_
+to be signaled in the xref:nng_cv_wait.adoc[`nng_cv_wait`] or
+xref:nng_cv_until.adoc[`nng_cv_until`] functions.
+
+The caller must have have ownership of the mutex that was used when
+_cv_ was allocated.
+
+NOTE: The caller should already have set the condition that the waiters
+will check, while holding the mutex.
+
+NOTE: The caller cannot predict which waiter will be woken, and so the design must
+ensure that it is sufficient that _any_ waiter be woken.
+When in doubt, it is safer to use xref:nng_cv_wake.adoc[`nng_cv_wake`].
+
+### Return Values
+
+None.
+
+### Errors
+
+None.
+
+### See Also
+
+xref:nng_cv_alloc.adoc[nng_cv_alloc],
+xref:nng_cv_until.adoc[nng_cv_until],
+xref:nng_cv_wait.adoc[nng_cv_wait],
+xref:nng_cv_wake.adoc[nng_cv_wake],
+xref:nng_mtx_alloc.adoc[nng_mtx_alloc],
+xref:nng_mtx_lock.adoc[nng_mtx_lock],
+xref:nng_mtx_unlock.adoc[nng_mtx_unlock],
+xref:nng.adoc[nng]
diff --git a/docs/ref/thr/nng_mtx_alloc.adoc b/docs/ref/thr/nng_mtx_alloc.adoc
new file mode 100644
index 00000000..88d2bccc
--- /dev/null
+++ b/docs/ref/thr/nng_mtx_alloc.adoc
@@ -0,0 +1,40 @@
+## nng_mtx_alloc
+
+Allocate mutex.
+
+### Synopsis
+
+```c
+#include <nng/nng.h>
+#include <nng/supplemental/util/platform.h>
+
+typedef struct nng_mtx nng_mtx;
+
+int nng_mtx_alloc(nng_mtx **mtxp);
+```
+
+### Description
+
+The `nng_mtx_alloc` function allocates mutex and returns it in _mtxp_.
+
+The mutex objects created by this function are suitable only for simple lock and unlock operations, and are not recursive.
+Every effort has been made to use light-weight underlying primitives when available.
+
+Mutex (mutual exclusion) objects can be thought of as binary semaphores,
+where only a single thread of execution is permitted to acquire the semaphore.
+
+Furthermore, a mutex can only be unlocked by the thread that locked it.
+
+### Return Values
+
+This function returns 0 on success, and non-zero otherwise.
+
+### Errors
+
+[horizontal]
+`NNG_ENOMEM`:: Insufficient free memory exists.
+
+### See Also
+
+xref:nng_mtx_free.adoc[nng_mtx_free],
+xref:nng_mtx_lock.adoc[nng_mtx_lock]
diff --git a/docs/ref/thr/nng_mtx_free.adoc b/docs/ref/thr/nng_mtx_free.adoc
new file mode 100644
index 00000000..0934326e
--- /dev/null
+++ b/docs/ref/thr/nng_mtx_free.adoc
@@ -0,0 +1,21 @@
+## nng_mtx_free
+
+Free mutex.
+
+### Synopsis
+
+```c
+#include <nng/nng.h>
+#include <nng/supplemental/util/platform.h>
+
+void nng_mtx_free(nng_mtx *mtx);
+```
+
+### Description
+
+The `nng_mtx_free` function frees the mutex _mtx_.
+The mutex must not be locked when this function is called.
+
+### See Also
+
+xref:nng_mtx_alloc.adoc[nng_mtx_alloc]
diff --git a/docs/ref/thr/nng_mtx_lock.adoc b/docs/ref/thr/nng_mtx_lock.adoc
new file mode 100644
index 00000000..de723c69
--- /dev/null
+++ b/docs/ref/thr/nng_mtx_lock.adoc
@@ -0,0 +1,34 @@
+## nng_mtx_lock
+
+Lock mutex.
+
+### Synopsis
+
+```c
+#include <nng/nng.h>
+#include <nng/supplemental/util/platform.h>
+
+void nng_mtx_lock(nng_mtx *mtx);
+```
+
+### Description
+
+The `nng_mtx_lock` acquires exclusive ownership of the mutex _mtx_.
+If the lock is already owned, this function will wait until the current owner releases it with xref:nng_mtx_unlock.adoc[`nng_mtx_unlock`].
+
+If multiple threads are waiting for the lock, the order of acquisition is not specified.
+
+NOTE: A mutex can _only_ be unlocked by the thread that locked it.
+
+IMPORTANT: Mutex locks are _not_ recursive.footnote:[_NNG_ offers neither a non-blocking variant that can fail,
+nor recursive mutexes.
+This is by design, as typically the need for them is the result of poor design.
+If such capabilities are needed, they may be synthesized fairly easily from mutexes and condition variables.]
+
+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.
+
+### See Also
+
+xref:nng_mtx_alloc.adoc[nng_mtx_alloc],
+xref:nng_mtx_unlock.adoc[nng_mtx_unlock]
diff --git a/docs/ref/thr/nng_mtx_unlock.adoc b/docs/ref/thr/nng_mtx_unlock.adoc
new file mode 100644
index 00000000..8c4ee374
--- /dev/null
+++ b/docs/ref/thr/nng_mtx_unlock.adoc
@@ -0,0 +1,24 @@
+## nng_mtx_unlock
+
+Unlock mutex.
+
+### Synopsis
+
+```c
+#include <nng/nng.h>
+#include <nng/supplemental/util/platform.h>
+
+void nng_mtx_unlock(nng_mtx *mtx);
+```
+
+### Description
+
+The `nng_mtx_unlock` relinquishes ownership of the mutex _mtx_ that was previously acquired via xref:nng_mtx_lock.adoc[`nng_mtx_lock`].
+
+IMPORTANT: 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.
+
+### See Also
+
+xref:nng_mtx_alloc.adoc[nng_mtx_alloc],
+xref:nng_mtx_lock.adoc[nng_mtx_lock]
diff --git a/docs/ref/thr/nng_thread_create.adoc b/docs/ref/thr/nng_thread_create.adoc
new file mode 100644
index 00000000..7d59cd1b
--- /dev/null
+++ b/docs/ref/thr/nng_thread_create.adoc
@@ -0,0 +1,56 @@
+## nng_thread_create
+
+Create thread.
+
+### Synopsis
+
+```c
+#include <nng/nng.h>
+#include <nng/supplemental/util/platform.h>
+
+typedef struct nng_thread nng_thread;
+
+int nng_thread_create(nng_thread **thrp, void (*func)(void *), void *arg);
+```
+
+### Description
+
+The `nng_thread_create` function creates a single thread of execution, running _func_ with the argument _arg_.
+The thread is started immediately.
+A pointer to the thread object is returned in _thrp_.
+
+The intention of this program is to facilitate writing parallel programs.
+Threads created by this program will be based upon the underlying threading mechanism of the system.
+This may include use of coroutines.
+
+Using threads created by this function can make it easy to write programs that use simple sequential execution, using functions that would otherwise normally wait synchronously for completion.
+
+When the thread is no longer needed, the xref:nng_thread_destroy.adoc[`nng_thread_destroy`] function should be used to reap it.
+(This function will block waiting for _func_ to return.)
+
+IMPORTANT: Thread objects created by this function may not be real system level threads capable of performing blocking I/O operations using normal blocking system calls.
+If use of blocking system calls is required (not including APIs provided by the _NNG_ library itself of course), then real OS-specific threads should be created instead (such as with `pthread_create` or similar functions.)
+
+IMPORTANT: Thread objects created by this function cannot be passed to any system threading functions.
+
+TIP: The system may impose limits on the number of threads that can be created.
+Typically applications should not create more than a dozen of these.
+If greater concurrency or scalability is needed, consider instead using an xref:../aio/index.adoc[asynchronous] model.
+
+TIP: Threads can be synchronized using xref:nng_mtx_alloc.adoc[mutexes] and xref:nng_cv_alloc.adoc[condition variables].
+
+### Return Values
+
+This function returns 0 on success, and non-zero otherwise.
+
+### Errors
+
+[horizontal]
+`NNG_ENOMEM`:: Insufficient free memory exists.
+
+### See Also
+
+xref:../aio/index.adoc[Asynchronous I/O],
+xref:nng_cv_alloc.adoc[nng_cv_alloc],
+xref:nng_mtx_alloc.adoc[nng_mtx_alloc],
+xref:nng_thread_destroy.adoc[nng_thread_destroy]
diff --git a/docs/ref/thr/nng_thread_destroy.adoc b/docs/ref/thr/nng_thread_destroy.adoc
new file mode 100644
index 00000000..82ebc0ec
--- /dev/null
+++ b/docs/ref/thr/nng_thread_destroy.adoc
@@ -0,0 +1,23 @@
+## nng_thread_destroy
+
+Destroy thread.
+
+### Synopsis
+
+```c
+#include <nng/nng.h>
+#include <nng/supplemental/util/platform.h>
+
+void nng_thread_destroy(nng_thread *thread);
+```
+
+### Description
+
+The `nng_thread_destroy` function reaps the _thread_.
+It waits for the thread function to return, and then deallocates the resources for the thread.
+
+IMPORTANT: Do not call this function from the thread function itself, or a deadlock will occur.
+
+### See Also
+
+xref:nng_thread_create.adoc[nng_thread_create]
diff --git a/docs/ref/thr/nng_thread_set_name.adoc b/docs/ref/thr/nng_thread_set_name.adoc
new file mode 100644
index 00000000..1b3ad2e7
--- /dev/null
+++ b/docs/ref/thr/nng_thread_set_name.adoc
@@ -0,0 +1,27 @@
+## nng_thread_set_name
+
+Set thread name.
+
+### Synopsis
+
+```c
+#include <nng/nng.h>
+#include <nng/supplemental/util/platform.h>
+
+void nng_thread_set_name(nng_thread *thread, const char *name);
+```
+
+### Description
+
+The `nng_thread_set_name` function attempts to set the name for the _thread_ to _name_.
+
+If _thread_ is `NULL`, then the name is set for the calling thread.
+
+Support for this, and how names are exposed, varies between platform implementations.
+This function is intended to facilitate debugging applications that have many threads.
+
+TIP: Internal threads created by _NNG_ will have names beginning with `nng:`.
+
+### See Also
+
+xref:nng_thread_create.adoc[nng_thread_create]