summaryrefslogtreecommitdiff
path: root/docs/reference/src/api/context
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2024-03-26 07:55:58 -0700
committerGarrett D'Amore <garrett@damore.org>2024-03-26 07:55:58 -0700
commit90b02493491e7ea6f962081efde4e29a1fd794c4 (patch)
tree597d79822e1e74fc18afefefc120c0470d23c6ff /docs/reference/src/api/context
parent87e5fc287fedb14656f964254f9b5c738c72b72a (diff)
downloadnng-90b02493491e7ea6f962081efde4e29a1fd794c4.tar.gz
nng-90b02493491e7ea6f962081efde4e29a1fd794c4.tar.bz2
nng-90b02493491e7ea6f962081efde4e29a1fd794c4.zip
More updates.
Diffstat (limited to 'docs/reference/src/api/context')
-rw-r--r--docs/reference/src/api/context/index.md160
-rw-r--r--docs/reference/src/api/context/nng_ctx_close.md41
-rw-r--r--docs/reference/src/api/context/nng_ctx_get.md112
-rw-r--r--docs/reference/src/api/context/nng_ctx_getopt.md116
-rw-r--r--docs/reference/src/api/context/nng_ctx_id.md31
-rw-r--r--docs/reference/src/api/context/nng_ctx_open.md56
-rw-r--r--docs/reference/src/api/context/nng_ctx_recv.md56
-rw-r--r--docs/reference/src/api/context/nng_ctx_recvmsg.md50
-rw-r--r--docs/reference/src/api/context/nng_ctx_send.md68
-rw-r--r--docs/reference/src/api/context/nng_ctx_sendmsg.md67
-rw-r--r--docs/reference/src/api/context/nng_ctx_set.md94
-rw-r--r--docs/reference/src/api/context/nng_ctx_setopt.md98
12 files changed, 949 insertions, 0 deletions
diff --git a/docs/reference/src/api/context/index.md b/docs/reference/src/api/context/index.md
new file mode 100644
index 00000000..d5a3fc90
--- /dev/null
+++ b/docs/reference/src/api/context/index.md
@@ -0,0 +1,160 @@
+# nng_ctx
+
+## NAME
+
+nng_ctx --- protocol context
+
+## SYNOPSIS
+
+```c
+#include <nng/nng.h>
+
+typedef struct nng_ctx_s nng_ctx
+```
+
+## DESCRIPTION
+
+An `nng_ctx`{{hi:context}} is a handle to an underlying context object,
+which keeps the protocol state for some stateful protocols.
+The purpose of a separate context object is to permit applications to
+share a single [socket](../socket/index.md), with its various underlying
+[dialers](nng_dialer.md),
+[listeners](nng_listener.md),
+[pipes](nng_pipe.md),
+while still benefiting from separate state tracking.
+
+For example, a [_REQ_](../protocols/req.md) context will contain the request ID
+of any sent request, a timer to retry the request on failure, and so forth.
+A separate context on the same socket can have similar data, but corresponding
+to a completely different request.
+
+> [!NOTE]
+> The `nng_ctx` structure is always passed by value (both
+> for input parameters and return values), and should be treated opaquely.
+> Passing structures this way gives the compiler a chance to perform
+> accurate type checks in functions passing values of this type.
+
+All contexts share the same socket, and so some options, as well as the
+underlying transport details, will be common to all contexts on that socket.
+
+Protocols that make use of contexts will also have a default context
+that is used when the socket global operations are used.
+Operations using the global context will generally not interfere with
+any other contexts, except that certain socket options may affect socket
+global behavior.
+
+{{hi:concurrent}}{{hi:raw mode}}
+Historically, applications wanting to use a stateful protocol concurrently
+would have to resort to [raw mode](../overview/raw.md) sockets, which bypasses
+much of the various protocol handling, leaving it to up to the application
+to do so.
+Contexts make it possible to still benefit from advanced protocol handling,
+including timeouts, retries, and matching requests to responses, while doing so
+concurrently.
+
+> [!TIP]
+> Contexts are an excellent mechanism to use when building concurrent
+> applications, and should be used in lieu of
+> [raw mode](../overview/raw.md) sockets when possible.
+
+## Caveats
+
+Not every protocol supports separate contexts.
+See the protocol-specific documentation for further details about whether
+contexts are supported, and details about what options are supported for
+contexts.
+
+Use of file descriptor polling (with descriptors obtained using the
+[`NNG_OPT_RECVFD`](nng_options.md#NNG_OPT_RECVFD) or
+[`NNG_OPT_SENDFD`](nng_options.md#NNG_OPT_SENDFD) options) while contexts
+are in use on the same socket is not supported, and may lead to unpredictable
+behavior. These asynchronous methods should not be mixed on the same socket.
+
+[Raw mode](../overview/raw.md) sockets do not support contexts, since
+there is generally no state tracked for them, and thus contexts make no sense.
+
+## Initialization
+
+A context may be initialized using the macro `NNG_CTX_INITIALIZER`
+before it is opened, to prevent confusion with valid open contexts.
+
+## Example
+
+The following program fragment demonstrates the use of contexts to implement
+a concurrent [_REP_](../protocols/rep.md) service that simply echos messages back
+to the sender.
+
+```c
+struct echo_context {
+ nng_ctx ctx;
+ nng_aio *aio;
+ enum { INIT, RECV, SEND } state;
+};
+
+void
+echo(void *arg)
+{
+ struct echo_context *ec = arg;
+
+ switch (ec->state) {
+ case INIT:
+ ec->state = RECV;
+ nng_ctx_recv(ec->ctx, ec->aio);
+ return;
+ case RECV:
+ if (nng_aio_result(ec->aio) != 0) {
+ // ... handle error
+ }
+ // We reuse the message on the ec->aio
+ ec->state = SEND;
+ nng_ctx_send(ec->ctx, ec->aio);
+ return;
+ case SEND:
+ if (nng_aio_result(ec->aio) != 0) {
+ // ... handle error
+ }
+ ec->state = RECV;
+ nng_ctx_recv(ec->ctx, ec->aio);
+ return;
+ }
+}
+```
+
+Given the above fragment, the following example shows setting up the
+service. It assumes that the [socket](nng_socket.md) has already been
+created and any transports set up as well with functions such as
+[`nng_dial()`](nng_dial.md) or [`nng_listen()`](nng_listen.md).
+
+```c
+#define CONCURRENCY 1024
+
+echo_context ecs[CONCURRENCY];
+
+void
+start_echo_service(nng_socket rep_socket)
+{
+ for (int i = 0; i < CONCURRENCY; i++) {
+ // error checks elided for clarity
+ nng_ctx_open(ec[i].ctx, rep_socket)
+ nng_aio_alloc(ec[i].aio, echo, &e[i]);
+ ec[i].state = INIT;
+ echo(&ec[i]); // start it running
+ }
+}
+```
+
+## SEE ALSO
+
+[nng_ctx_close](nng_ctx_close.md),
+[nng_ctx_open](nng_ctx_open.md),
+[nng_ctx_get](nng_ctx_get.md),
+[nng_ctx_id](nng_ctx_id.md)
+[nng_ctx_recv](nng_ctx_recv.md),
+[nng_ctx_recvmsg](nng_ctx_recvmsg.md),
+[nng_ctx_send](nng_ctx_send.md),
+[nng_ctx_sendmsg](nng_ctx_sendmsg.md),
+[nng_ctx_set](nng_ctx_set.md),
+[nng_dialer](nng_dialer.md),
+[nng_listener](nng_listener.md),
+[nng_socket](../socket/index.md),
+[nng_options](nng_options.md)
diff --git a/docs/reference/src/api/context/nng_ctx_close.md b/docs/reference/src/api/context/nng_ctx_close.md
new file mode 100644
index 00000000..e33dd843
--- /dev/null
+++ b/docs/reference/src/api/context/nng_ctx_close.md
@@ -0,0 +1,41 @@
+# nng_ctx_close
+
+## NAME
+
+nng_ctx_close --- close context
+
+## SYNOPSIS
+
+```c
+#include <nng/nng.h>
+
+int nng_ctx_close(nng_ctx ctx);
+```
+
+## DESCRIPTION
+
+The `nng_ctx_close()` function closes the context _ctx_.
+Messages that have been submitted for sending may be flushed or delivered,
+depending upon the transport.
+
+Further attempts to use the context after this call returns will result
+in `NNG_ECLOSED`.
+Threads waiting for operations on the context when this
+call is executed may also return with an `NNG_ECLOSED` result.
+
+> [!NOTE]
+> Closing the socket associated with _ctx_
+> (using [`nng_close()`](../socket/nng_close.md)) also closes this context.
+
+## RETURN VALUES
+
+This function returns 0 on success, and non-zero otherwise.
+
+## ERRORS
+
+- `NNG_ECLOSED`: The context _ctx_ is already closed or was never opened.
+
+## SEE ALSO
+
+[nng_close](nng_close.md),
+[nng_ctx_open](nng_ctx_open.md)
diff --git a/docs/reference/src/api/context/nng_ctx_get.md b/docs/reference/src/api/context/nng_ctx_get.md
new file mode 100644
index 00000000..35407f18
--- /dev/null
+++ b/docs/reference/src/api/context/nng_ctx_get.md
@@ -0,0 +1,112 @@
+# nng_ctx_get
+
+## NAME
+
+nng_ctx_get --- get context option
+
+## SYNOPSIS
+
+```c
+#include <nng/nng.h>
+
+int nng_ctx_get(nng_ctx ctx, const char *opt, void *val, size_t *valszp);
+
+int nng_ctx_get_bool(nng_ctx ctx, const char *opt, bool *bvalp);
+
+int nng_ctx_get_int(nng_ctx ctx, const char *opt, int *ivalp);
+
+int nng_ctx_get_ms(nng_ctx ctx, const char *opt, nng_duration *durp);
+
+int nng_ctx_get_size(nng_ctx ctx, const char *opt, size_t *zp);
+
+int nng_ctx_get_string(nng_ctx ctx, const char *opt, char **strp);
+
+int nng_ctx_get_uint64(nng_ctx ctx, const char *opt, uint64_t *u64p);
+```
+
+## DESCRIPTION
+
+{{hi:options, context}}
+The `nng_ctx_get()` functions are used to retrieve option values for
+the [context](index.md) _ctx_.
+The actual options that may be retrieved in this way vary.
+A number of them are documented in [nng_options](../socket/nng_options.md).
+
+> [!NOTE]
+> Context options are protocol specific.
+> The details will be documented with the protocol.
+
+### Forms
+
+In all of these forms, the option _opt_ is retrieved from the context _ctx_.
+The forms vary based on the type of the option they take.
+
+The details of the type, size, and semantics of the option will depend
+on the actual option, and will be documented with the option itself.
+
+- `nng_ctx_get()`:\
+ This function is untyped and can be used to retrieve the value of any option.
+ The caller must store a pointer to a buffer to receive the value in _val_,
+ and the size of the buffer shall be stored at the location referenced by
+ _valszp_.\
+ \
+ When the function returns, the actual size of the data copied (or that
+ would have been copied if sufficient space were present) is stored at
+ the location referenced by _valszp_.
+ If the caller's buffer is not large enough to hold the entire object,
+ then the copy is truncated.
+ Therefore the caller should check for truncation by verifying that the
+ returned size in _valszp_ does not exceed the original buffer size.\
+ \
+ It is acceptable to pass `NULL` for _val_ if the value in _valszp_ is zero.
+ This can be used to determine the size of the buffer needed to receive
+ the object.
+
+- `nng_ctx_get_bool()`:\
+ This function is for options which take a Boolean (`bool`).
+ The value will be stored at _ivalp_.
+
+- `nng_ctx_get_int()`:\
+ This function is for options which take an integer (`int`).
+ The value will be stored at _ivalp_.
+
+- `nng_ctx_get_ms()`:\
+ This function is used to retrieve time [durations](nng_duration.md)
+ (such as timeouts), stored in _durp_ as a number of milliseconds.
+ (The special value {{i:`NNG_DURATION_INFINITE`}} means an infinite amount of time, and
+ the special value {{i:`NNG_DURATION_DEFAULT`}} means a context-specific default.)
+- `nng_ctx_get_size()`:\
+ This function is used to retrieve a size into the pointer _zp_,
+ typically for buffer sizes, message maximum sizes, and similar options.
+- `nng_ctx_get_string()`:\
+ This function is used to retrieve a string into _strp_.
+ This string is created from the source using [`nng_strdup()`](nng_strdup.md)
+ and consequently must be freed by the caller using
+ [`nng_strfree()`](nng_strfree.md) when it is no longer needed.
+
+- `nng_ctx_get_uint64()`:\
+ This function is used to retrieve a 64-bit unsigned value into the value
+ referenced by _u64p_.
+ This is typically used for options related to identifiers, network
+ numbers, and similar.
+
+## RETURN VALUES
+
+These functions return 0 on success, and non-zero otherwise.
+
+## ERRORS
+
+- `NNG_EBADTYPE`: Incorrect type for option.
+- `NNG_ECLOSED`: Parameter _s_ does not refer to an open socket.
+- `NNG_EINVAL`: Size of destination _val_ too small for object.
+- `NNG_ENOMEM`: Insufficient memory exists.
+- `NNG_ENOTSUP`: The option _opt_ is not supported.
+- `NNG_EWRITEONLY`: The option _opt_ is write-only.
+
+## SEE ALSO
+
+[nng_ctx_set](nng_ctx_set.md),
+[nng_strdup](nng_strdup.md),
+[nng_strfree](nng_strfree.md),
+[nng_duration](nng_duration.md),
+[nng_options](../socket/nng_options.md)
diff --git a/docs/reference/src/api/context/nng_ctx_getopt.md b/docs/reference/src/api/context/nng_ctx_getopt.md
new file mode 100644
index 00000000..83a648d0
--- /dev/null
+++ b/docs/reference/src/api/context/nng_ctx_getopt.md
@@ -0,0 +1,116 @@
+# nng_ctx_getopt
+
+## NAME
+
+nng_ctx_getopt --- get context option (deprecated)
+
+## SYNOPSIS
+
+```c
+#include <nng/nng.h>
+
+int nng_ctx_getopt(nng_ctx ctx, const char *opt, void *val, size_t *valszp);
+
+int nng_ctx_getopt_bool(nng_ctx ctx, const char *opt, bool *bvalp);
+
+int nng_ctx_getopt_int(nng_ctx ctx, const char *opt, int *ivalp);
+
+int nng_ctx_getopt_ms(nng_ctx ctx, const char *opt, nng_duration *durp);
+
+int nng_ctx_getopt_size(nng_ctx ctx, const char *opt, size_t *zp);
+
+int nng_ctx_getopt_string(nng_ctx ctx, const char *opt, char **strp);
+
+int nng_ctx_getopt_uint64(nng_ctx ctx, const char *opt, uint64_t *u64p);
+```
+
+## DESCRIPTION
+
+> [!IMPORTANT]
+> These functions are deprecated. Please see [nng_ctx_get](nng_ctx_get.md).
+> They may not be present if the library was built with `NNG_ELIDE_DEPRECATED`.
+> They may also be removed entirely in a future version of _NNG_.
+
+The `nng_ctx_getopt()` functions are used to retrieve option values for
+the [context](index.md) _ctx_.
+The actual options that may be retrieved in this way vary.
+
+> [!NOTE]
+> Context options are protocol specific.
+> The details will be documented with the protocol.
+
+### Forms
+
+In all of these forms, the option _opt_ is retrieved from the context _ctx_.
+The forms vary based on the type of the option they take.
+
+The details of the type, size, and semantics of the option will depend
+on the actual option, and will be documented with the option itself.
+
+- `nng_ctx_getopt()`:\
+ This function is untyped and can be used to retrieve the value of any option.
+ The caller must store a pointer to a buffer to receive the value in _val_,
+ and the size of the buffer shall be stored at the location referenced by
+ _valszp_.\
+ \
+ When the function returns, the actual size of the data copied (or that
+ would have been copied if sufficient space were present) is stored at
+ the location referenced by _valszp_.
+ If the caller's buffer is not large enough to hold the entire object,
+ then the copy is truncated.
+ Therefore the caller should check for truncation by verifying that the
+ returned size in _valszp_ does not exceed the original buffer size.\
+ \
+ It is acceptable to pass `NULL` for _val_ if the value in _valszp_ is zero.
+ This can be used to determine the size of the buffer needed to receive
+ the object.
+
+- `nng_ctx_getopt_bool()`:\
+ This function is for options which take a Boolean (`bool`).
+ The value will be stored at _ivalp_.
+
+- `nng_ctx_getopt_int()`:\
+ This function is for options which take an integer (`int`).
+ The value will be stored at _ivalp_.
+
+- `nng_ctx_getopt_ms()`:\
+ This function is used to retrieve time [durations](nng_duration.md)
+ (such as timeouts), stored in _durp_ as a number of milliseconds.
+ (The special value `NNG_DURATION_INFINITE` means an infinite amount of time, and
+ the special value `NNG_DURATION_DEFAULT` means a context-specific default.)
+
+- `nng_ctx_getopt_size()`:\
+ This function is used to retrieve a size into the pointer _zp_,
+ typically for buffer sizes, message maximum sizes, and similar options.
+
+- `nng_ctx_getopt_string()`:\
+ This function is used to retrieve a string into _strp_.
+ This string is created from the source using [`nng_strdup()`](../util/nng_strdup.md)
+ and consequently must be freed by the caller using
+ [`nng_strfree()`](../util/nng_strfree.md) when it is no longer needed.
+
+- `nng_ctx_getopt_uint64()`:\
+ This function is used to retrieve a 64-bit unsigned value into the value
+ referenced by _u64p_.
+ This is typically used for options related to identifiers, network
+ numbers, and similar.
+
+## RETURN VALUES
+
+These functions return 0 on success, and non-zero otherwise.
+
+## ERRORS
+
+- `NNG_EBADTYPE`: Incorrect type for option.
+- `NNG_ECLOSED`: Parameter _s_ does not refer to an open socket.
+- `NNG_EINVAL`: Size of destination _val_ too small for object.
+- `NNG_ENOMEM`: Insufficient memory exists.
+- `NNG_ENOTSUP`: The option _opt_ is not supported.
+- `NNG_EWRITEONLY`: The option _opt_ is write-only.
+
+## SEE ALSO
+
+[nng_strdup](../util/nng_strdup.md),
+[nng_strfree](../util/nng_strfree.md),
+[nng_duration](nng_duration.md),
+[nng_options](../socket/nng_options.md)
diff --git a/docs/reference/src/api/context/nng_ctx_id.md b/docs/reference/src/api/context/nng_ctx_id.md
new file mode 100644
index 00000000..9d8d7223
--- /dev/null
+++ b/docs/reference/src/api/context/nng_ctx_id.md
@@ -0,0 +1,31 @@
+# nng_ctx_id
+
+## NAME
+
+nng_ctx_id --- return numeric context identifier
+
+## SYNOPSIS
+
+```c
+#include <nng/nng.h>
+
+int nng_ctx_id(nng_ctx c);
+```
+
+## DESCRIPTION
+
+The `nng_ctx_id()` function returns a positive identifier for the context _c_,
+if it is valid.
+Otherwise it returns `-1`.
+
+> [!NOTE]
+> A context is considered valid if it was ever opened with
+> [`nng_ctx_open()`](nng_ctx_open.md) function.
+> Contexts that are allocated on the stack or statically should be
+> initialized with the macro `NNG_CTX_INITIALIZER` to ensure that
+> they cannot be confused with a valid context before they are opened.
+
+## RETURN VALUES
+
+This function returns the positive value for the context identifier, or
+`-1` if the context is invalid.
diff --git a/docs/reference/src/api/context/nng_ctx_open.md b/docs/reference/src/api/context/nng_ctx_open.md
new file mode 100644
index 00000000..b582e254
--- /dev/null
+++ b/docs/reference/src/api/context/nng_ctx_open.md
@@ -0,0 +1,56 @@
+# nng_ctx_open
+
+## NAME
+
+nng_ctx_open --- create context
+
+## SYNOPSIS
+
+```c
+#include <nng/nng.h>
+
+int nng_ctx_open(nng_ctx *ctxp, nng_socket s);
+```
+
+## DESCRIPTION
+
+The `nng_ctx_open()` function creates a separate {{i:context}} to be used with
+the socket _s_,
+and returns it at the location pointed by _ctxp_.
+
+> [!NOTE]
+> Not every protocol supports creation of separate contexts.
+
+Contexts allow the independent and concurrent use of stateful operations
+using the same socket.
+For example, two different contexts created on a
+[_REP_](../protocols/rep.md)
+socket can each receive requests, and send replies to them, without any
+regard to or interference with each other.
+
+> [!TIP]
+> Using contexts is an excellent way to write simpler concurrent
+> applications, while retaining the benefits of the protocol-specific
+> advanced processing, avoiding the need to bypass that with
+> {{hi:raw mode}}[raw mode](../overview/raw.md) sockets.
+
+> [!NOTE]
+> Use of contexts with [raw mode](../overview/raw.md) sockets is
+> nonsensical, and not supported.
+
+## RETURN VALUES
+
+This function returns 0 on success, and non-zero otherwise.
+
+## ERRORS
+
+- `NNG_ENOMEM`: Insufficient memory is available.
+- `NNG_ENOTSUP`: The protocol does not support separate contexts, or the socket was opened in raw mode.
+
+## SEE ALSO
+
+[nng_ctx_close](nng_ctx_close.md),
+[nng_ctx_get](nng_ctx_get.md),
+[nng_ctx_recv](nng_ctx_recv.md),
+[nng_ctx_send](nng_ctx_send.md),
+[nng_ctx_set](nng_ctx_set.md)
diff --git a/docs/reference/src/api/context/nng_ctx_recv.md b/docs/reference/src/api/context/nng_ctx_recv.md
new file mode 100644
index 00000000..2ef398ea
--- /dev/null
+++ b/docs/reference/src/api/context/nng_ctx_recv.md
@@ -0,0 +1,56 @@
+# nng_ctx_recv
+
+## NAME
+
+nng_ctx_recv --- receive message using context asynchronously
+
+## SYNOPSIS
+
+```c
+#include <nng/nng.h>
+
+void nng_ctx_recv(nng_ctx ctx, nng_aio *aio);
+```
+
+## DESCRIPTION
+
+The `nng_ctx_recv()` receives a [message](../msg/index.md) using the
+[context](index.md) _s_ asynchronously.
+
+When a message is successfully received by the context, it is
+stored in the _aio_ by an internal call equivalent to
+[`nng_aio_set_msg()`](../aio/nng_aio_set_msg.md), then the completion
+callback on the _aio_ is executed.
+In this case, [`nng_aio_result()`](../aio/nng_aio_result.md) will
+return zero.
+The callback function is responsible for retrieving the message
+and disposing of it appropriately.
+
+> [!IMPORTANT]
+> Failing to accept and dispose of messages in this
+> case can lead to memory leaks.
+
+If for some reason the asynchronous receive cannot be completed
+successfully (including by being canceled or timing out), then
+the callback will still be executed,
+but [`nng_aio_result()`](../aio/nng_aio_result.md) will be non-zero.
+
+> [!TIP]
+> The semantics of what receiving a message means varies from protocol to
+> protocol, so examination of the protocol documentation is encouraged.
+
+## ERRORS
+
+The following errors may be set on the _aio_, if the operation fails.
+
+- `NNG_ECANCELED`: The operation was aborted.
+- `NNG_ECLOSED`: The context _ctx_ is not open.
+- `NNG_ENOMEM`: Insufficient memory is available.
+- `NNG_ENOTSUP`: The protocol for context _ctx_ does not support receiving.
+- `NNG_ESTATE`: The context _ctx_ cannot receive data in this state.
+- `NNG_ETIMEDOUT`: The receive timeout expired.
+
+## SEE ALSO
+
+[Asynchronous I/O](../aio/index.md),
+[Messages](../msg/index.md)
diff --git a/docs/reference/src/api/context/nng_ctx_recvmsg.md b/docs/reference/src/api/context/nng_ctx_recvmsg.md
new file mode 100644
index 00000000..c0065dd3
--- /dev/null
+++ b/docs/reference/src/api/context/nng_ctx_recvmsg.md
@@ -0,0 +1,50 @@
+# nng_ctx_recvmsg
+
+## NAME
+
+nng_ctx_recvmsg --- receive message using socket
+
+## SYNOPSIS
+
+```c
+#include <nng/nng.h>
+
+int nng_ctx_recvmsg(nng_ctx ctx, nng_msg **msgp, int flags);
+```
+
+## DESCRIPTION
+
+The `nng_ctx_recvmsg()` receives a message on context _ctx_, storing the
+received message at the location pointed to by _msgp_.
+
+The _flags_ may contain the following value:
+
+- `NNG_FLAG_NONBLOCK`:\
+ The function returns immediately, even if no message is available.
+ Without this flag, the function will wait until a message is receivable
+ on the context _ctx_, or any configured timer expires.
+
+> [!TIP]
+> The semantics of what receiving a message means vary from protocol to
+> protocol, so examination of the protocol documentation is encouraged.
+
+## RETURN VALUES
+
+This function returns 0 on success, and non-zero otherwise.
+
+## ERRORS
+
+- `NNG_EAGAIN`: The operation would block, but `NNG_FLAG_NONBLOCK` was specified.
+- `NNG_ECLOSED`: The context or socket is not open.
+- `NNG_EINVAL`: An invalid set of _flags_ was specified.
+- `NNG_ENOMEM`: Insufficient memory is available.
+- `NNG_ENOTSUP`: The protocol does not support receiving.
+- `NNG_ESTATE`: The context cannot receive data in this state.
+- `NNG_ETIMEDOUT`: The operation timed out.
+
+## SEE ALSO
+
+[nng_msg_free()](../msg/nng_msg_free.md),
+[nng_ctx_open()](nng_ctx_open.md),
+[nng_ctx_recv()](nng_ctx_recv.md),
+[nng_ctx_sendmsg()](nng_ctx_sendmsg.md)
diff --git a/docs/reference/src/api/context/nng_ctx_send.md b/docs/reference/src/api/context/nng_ctx_send.md
new file mode 100644
index 00000000..9caad652
--- /dev/null
+++ b/docs/reference/src/api/context/nng_ctx_send.md
@@ -0,0 +1,68 @@
+# nng_ctx_send
+
+## NAME
+
+nng_ctx_send --- send message using context asynchronously
+
+## SYNOPSIS
+
+```c
+#include <nng/nng.h>
+
+void nng_ctx_send(nng_ctx ctx, nng_aio *aio);
+```
+
+## DESCRIPTION
+
+The `nng_ctx_send()` sends a [message](../msg/index.md) using the
+[context](nng_ctx.md) _ctx_ asynchronously.
+
+The message to send must have previously been set on the _aio_
+using the [`nng_aio_set_msg()`](../aio/nng_aio_set_msg.md) function.
+The function assumes ownership of the message.
+
+If the message was successfully queued for delivery to the socket,
+then the _aio_ will be completed, and [`nng_aio_result()`](../aio/nng_aio_result.md)
+will return zero.
+In this case the socket will dispose of the message when it is finished with it.
+
+> [!NOTE]
+> The operation will be completed, and the callback associated
+> with the _aio_ executed, as soon as the socket accepts the message
+> for sending.
+> This does _not_ indicate that the message was actually delivered, as it
+> may still be buffered in the sending socket, buffered in the receiving
+> socket, or in flight over physical media.
+
+If the operation fails for any reason (including cancellation or timeout),
+then the _aio_ callback will be executed and
+[`nng_aio_result()`](../aio/nng_aio_result.md) will return a non-zero error status.
+In this case, the callback has a responsibility to retrieve the message from
+the _aio_ with [`nng_aio_get_msg()`](../aio/nng_aio_get_msg.md) and dispose of
+it appropriately.
+(This may include retrying the send operation on the same or a different
+socket, or deallocating the message with [`nng_msg_free()`](../msg/nng_msg_free.md).
+
+> [!TIP]
+> The semantics of what sending a message means varies from protocol to
+> protocol, so examination of the protocol documentation is encouraged.
+
+## ERRORS
+
+- `NNG_ECANCELED`: The operation was aborted.
+- `NNG_ECLOSED`: The context _ctx_ is not open.
+- `NNG_EMSGSIZE`: The message is too large.
+- `NNG_ENOMEM`: Insufficient memory is available.
+- `NNG_ENOTSUP`: The protocol for context _ctx_ does not support sending.
+- `NNG_ESTATE`: The context _ctx_ cannot send data in this state.
+- `NNG_ETIMEDOUT`: The send timeout expired.
+
+## SEE ALSO
+
+[nng_aio_get_msg](../aio/nng_aio_get_msg.md),
+[nng_aio_set_msg](../aio/nng_aio_set_msg.md),
+[nng_ctx_sendmsg](nng_ctx_sendmsg.md),
+[nng_msg_alloc](../msg/nng_msg_alloc.md),
+[nng_msg_free](../msg/nng_msg_free.md),
+[Asynchronous I/O](../aio/index.md),
+[Messages](../msg/index.md)
diff --git a/docs/reference/src/api/context/nng_ctx_sendmsg.md b/docs/reference/src/api/context/nng_ctx_sendmsg.md
new file mode 100644
index 00000000..346f927d
--- /dev/null
+++ b/docs/reference/src/api/context/nng_ctx_sendmsg.md
@@ -0,0 +1,67 @@
+# nng_ctx_sendmsg()
+
+## NAME
+
+nng_ctx_sendmsg --- send message using context
+
+## SYNOPSIS
+
+```c
+#include <nng/nng.h>
+
+int nng_ctx_sendmsg(nng_ctx c, nng_msg *msg, int flags);
+```
+
+## DESCRIPTION
+
+The `nng_ctx_sendmsg()` sends message _msg_ using the context _ctx_.
+
+If the function returns zero, indicating it has accepted the message for
+delivery, then the _msg_ is owned by the socket _s_, and the caller
+must not make any further use of it.
+The socket will free the message when it is finished.
+
+If the function returns non-zero, then it is the caller's responsibility
+to dispose of the _msg_, which may include freeing it, sending it to
+another socket, or simply trying again later.
+
+> [!TIP]
+> The semantics of what sending a message means vary from protocol to
+> protocol, so examination of the protocol documentation is encouraged.
+
+The _flags_ may contain the following value:
+
+- `NNG_FLAG_NONBLOCK`:\
+ The function returns immediately, regardless of whether
+ the context is able to accept the data or not.
+ If the context is unable to accept the data (such as if backpressure exists
+ because the peers are consuming messages too slowly, or no peer is present),
+ then the function will return with `NNG_EAGAIN`.
+ If this flag is not specified, then the function will block if such a
+ condition exists.
+
+> [!NOTE]
+> Regardless of the presence or absence of `NNG_FLAG_NONBLOCK`, there may
+> be queues between the sender and the receiver.
+> Furthermore, there is no guarantee that the message has actually been delivered.
+> Finally, with some protocols, the semantic is implicitly `NNG_FLAG_NONBLOCK`.
+
+## RETURN VALUES
+
+This function returns 0 on success, and non-zero otherwise.
+
+## ERRORS
+
+- `NNG_EAGAIN`: The operation would block, but `NNG_FLAG_NONBLOCK` was specified.
+- `NNG_ECLOSED`: The context or socket is not open.
+- `NNG_EINVAL`: An invalid set of _flags_ was specified.
+- `NNG_EMSGSIZE`: The value of _size_ is too large.
+- `NNG_ENOMEM`: Insufficient memory is available.
+- `NNG_ENOTSUP`: The protocol does not support sending.
+- `NNG_ESTATE`: The context cannot send data in this state.
+- `NNG_ETIMEDOUT`: The operation timed out.
+
+## SEE ALSO
+
+[nng_ctx_send()](nng_ctx_send.md),
+[Messages](../msg/index.md)
diff --git a/docs/reference/src/api/context/nng_ctx_set.md b/docs/reference/src/api/context/nng_ctx_set.md
new file mode 100644
index 00000000..b3237717
--- /dev/null
+++ b/docs/reference/src/api/context/nng_ctx_set.md
@@ -0,0 +1,94 @@
+# nng_ctx_set
+
+## NAME
+
+nng_ctx_set --- set context option
+
+## SYNOPSIS
+
+```c
+#include <nng/nng.h>
+
+int nng_ctx_set(nng_ctx ctx, const char *opt, const void *val, size_t valsz);
+
+int nng_ctx_set_bool(nng_ctx ctx, const char *opt, int bval);
+
+int nng_ctx_set_int(nng_ctx ctx, const char *opt, int ival);
+
+int nng_ctx_set_ms(nng_ctx ctx, const char *opt, nng_duration dur);
+
+int nng_ctx_set_size(nng_ctx ctx, const char *opt, size_t z);
+
+int nng_ctx_set_string(nng_ctx ctx, const char *opt, const char *str);
+
+int nng_ctx_set_uint64(nng_ctx ctx, const char *opt, uint64_t u64);
+```
+
+## DESCRIPTION
+
+{{hi:options, context}}
+The `nng_ctx_set()` functions are used to configure options for
+the context _ctx_.
+The actual options that may be configured in this way vary, and are
+specified by _opt_.
+
+> [!NOTE]
+> Context options are protocol specific.
+> The details will be documented with the protocol.
+
+### Forms
+
+The details of the type, size, and semantics of the option will depend
+on the actual option, and will be documented with the option itself.
+
+- `nng_ctx_set()`:\
+ This function is untyped, and can be used to configure any arbitrary data.
+ The _val_ pointer addresses the data to copy, and _valsz_ is the
+ size of the objected located at _val_.
+
+- `nng_ctx_set_bool()`:\
+ This function is for options which take a Boolean (`bool`).
+ The _bval_ is passed to the option.
+
+- `nng_ctx_set_int()`:\
+ This function is for options which take an integer (`int`).
+ The _ival_ is passed to the option.
+
+- `nng_ctx_set_ms()`:\
+ This function is used to configure time durations (such as timeouts) using
+ type [`nng_duration`](nng_duration.md).
+ The duration _dur_ is an integer number of milliseconds.
+
+- `nng_ctx_set_size()`:\
+ This function is used to configure a size, _z_, typically for buffer sizes,
+ message maximum sizes, and similar options.
+
+- `nng_ctx_set_string()`:\
+ This function is used to pass configure a string, _str_.
+ Strings passed this way must be legal UTF-8 or ASCII strings, terminated
+ with a `NUL` (`\0`) byte.
+ (Other constraints may apply as well, see the documentation for each option
+ for details.)
+
+- `nng_ctx_set_uint64()`:\
+ This function is used to configure a 64-bit unsigned value, _u64_.
+ This is typically used for options related to identifiers, network numbers,
+ and similar.
+
+## RETURN VALUES
+
+These functions return 0 on success, and non-zero otherwise.
+
+## ERRORS
+
+- `NNG_ECLOSED`: Parameter _s_ does not refer to an open socket.
+- `NNG_EINVAL`: The value being passed is invalid.
+- `NNG_ENOTSUP`: The option _opt_ is not supported.
+- `NNG_EREADONLY`: The option _opt_ is read-only.
+- `NNG_ESTATE`: The socket is in an inappropriate state for setting this option.
+
+## SEE ALSO
+
+[nng_ctx_get](nng_ctx_get),
+[nng_socket_set](../socket/nng_socket_get),
+[nng_options](nng_options)
diff --git a/docs/reference/src/api/context/nng_ctx_setopt.md b/docs/reference/src/api/context/nng_ctx_setopt.md
new file mode 100644
index 00000000..f62b6857
--- /dev/null
+++ b/docs/reference/src/api/context/nng_ctx_setopt.md
@@ -0,0 +1,98 @@
+# nng_ctx_setopt
+
+## NAME
+
+nng_ctx_setopt --- set context option (deprecated)
+
+## SYNOPSIS
+
+```c
+#include <nng/nng.h>
+
+int nng_ctx_setopt(nng_ctx ctx, const char *opt, const void *val, size_t valsz);
+
+int nng_ctx_setopt_bool(nng_ctx ctx, const char *opt, int bval);
+
+int nng_ctx_setopt_int(nng_ctx ctx, const char *opt, int ival);
+
+int nng_ctx_setopt_ms(nng_ctx ctx, const char *opt, nng_duration dur);
+
+int nng_ctx_setopt_size(nng_ctx ctx, const char *opt, size_t z);
+
+int nng_ctx_setopt_string(nng_ctx ctx, const char *opt, const char *str);
+
+int nng_ctx_setopt_uint64(nng_ctx ctx, const char *opt, uint64_t u64);
+```
+
+## DESCRIPTION
+
+> [!IMPORTANT]
+> These functions are deprecated.
+> Please see [nng_ctx_set()](nng_ctx_set.md).
+> They may not be present if the library was built with `NNG_ELIDE_DEPRECATED`.
+> They may also be removed entirely in a future version of _NNG_.
+
+The `nng_ctx_setopt()` functions are used to configure options for
+the context _ctx_.
+The actual options that may be configured in this way vary, and are
+specified by _opt_.
+
+> [!NOTE]
+> Context options are protocol specific.
+> The details will be documented with the protocol.
+
+### Forms
+
+The details of the type, size, and semantics of the option will depend
+on the actual option, and will be documented with the option itself.
+
+- `nng_ctx_setopt()`:\
+ This function is untyped, and can be used to configure any arbitrary data.
+ The _val_ pointer addresses the data to copy, and _valsz_ is the
+ size of the objected located at _val_.
+
+- `nng_ctx_setopt_bool()`:\
+ This function is for options which take a Boolean (`bool`).
+ The _bval_ is passed to the option.
+
+- `nng_ctx_setopt_int()`:\
+ This function is for options which take an integer (`int`).
+ The _ival_ is passed to the option.
+
+- `nng_ctx_setopt_ms()`:\
+ This function is used to configure time durations (such as timeouts) using
+ type [`nng_duration`](nng_duration.md).
+ The duration _dur_ is an integer number of milliseconds.
+
+- `nng_ctx_setopt_size()`:\
+ This function is used to configure a size, _z_, typically for buffer sizes,
+ message maximum sizes, and similar options.
+
+- `nng_ctx_setopt_string()`:\
+ This function is used to pass configure a string, _str_.
+ Strings passed this way must be legal UTF-8 or ASCII strings, terminated
+ with a `NUL` (`\0`) byte.
+ (Other constraints may apply as well, see the documentation for each option
+ for details.)
+
+- `nng_ctx_setopt_uint64()`:\
+ This function is used to configure a 64-bit unsigned value, _u64_.
+ This is typically used for options related to identifiers, network numbers,
+ and similar.
+
+## RETURN VALUES
+
+These functions return 0 on success, and non-zero otherwise.
+
+## ERRORS
+
+- `NNG_ECLOSED`: Parameter _s_ does not refer to an open socket.
+- `NNG_EINVAL`: The value being passed is invalid.
+- `NNG_ENOTSUP`: The option _opt_ is not supported.
+- `NNG_EREADONLY`: The option _opt_ is read-only.
+- `NNG_ESTATE`: The socket is in an inappropriate state for setting this option.
+
+## SEE ALSO
+
+[nng_ctx_set](nng_ctx_set.md),
+[nng_options](nng_options.md)