diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/man/libnng.3.adoc | 19 | ||||
| -rw-r--r-- | docs/man/nng_ctx.5.adoc | 176 | ||||
| -rw-r--r-- | docs/man/nng_ctx_close.3.adoc | 54 | ||||
| -rw-r--r-- | docs/man/nng_ctx_get.3.adoc | 101 | ||||
| -rw-r--r-- | docs/man/nng_ctx_id.3.adoc | 51 | ||||
| -rw-r--r-- | docs/man/nng_ctx_open.3.adoc | 71 | ||||
| -rw-r--r-- | docs/man/nng_ctx_recv.3.adoc | 74 | ||||
| -rw-r--r-- | docs/man/nng_ctx_recvmsg.3.adoc | 63 | ||||
| -rw-r--r-- | docs/man/nng_ctx_send.3.adoc | 88 | ||||
| -rw-r--r-- | docs/man/nng_ctx_sendmsg.3.adoc | 84 | ||||
| -rw-r--r-- | docs/man/nng_ctx_set.3.adoc | 100 | ||||
| -rw-r--r-- | docs/ref/SUMMARY.md | 2 | ||||
| -rw-r--r-- | docs/ref/api/ctx.md | 261 | ||||
| -rw-r--r-- | docs/ref/api/index.md | 1 | ||||
| -rw-r--r-- | docs/ref/xref.md | 14 |
15 files changed, 276 insertions, 883 deletions
diff --git a/docs/man/libnng.3.adoc b/docs/man/libnng.3.adoc index 877893e3..36560102 100644 --- a/docs/man/libnng.3.adoc +++ b/docs/man/libnng.3.adoc @@ -89,25 +89,6 @@ The following functions are used in the asynchronous model: |=== -=== Protocol Contexts - -The following functions are useful to separate the protocol processing -from a socket object, into a separate context. -This can allow multiple contexts to be created on a single socket for -concurrent applications. - -|=== -|xref:nng_ctx_close.3.adoc[nng_ctx_close()]|close context -|xref:nng_ctx_get.3.adoc[nng_ctx_get()]|get context option -|xref:nng_ctx_id.3.adoc[nng_ctx_id()]|get numeric context identifier -|xref:nng_ctx_open.3.adoc[nng_ctx_open()]|create context -|xref:nng_ctx_recv.3.adoc[nng_ctx_recv()]|receive message using context asynchronously -|xref:nng_ctx_recvmsg.3.adoc[nng_ctx_recvmsg()]|receive a message using context -|xref:nng_ctx_send.3.adoc[nng_ctx_send()]|send message using context asynchronously -|xref:nng_ctx_sendmsg.3.adoc[nng_ctx_sendmsg()]|send a message using context -|xref:nng_ctx_set.3.adoc[nng_ctx_set()]|set context option -|=== - === Devices, Relays The following function family is used to create forwarders or relayers diff --git a/docs/man/nng_ctx.5.adoc b/docs/man/nng_ctx.5.adoc deleted file mode 100644 index 63e8736c..00000000 --- a/docs/man/nng_ctx.5.adoc +++ /dev/null @@ -1,176 +0,0 @@ -= nng_ctx(5) -// -// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech> -// Copyright 2018 Capitar IT Group BV <info@capitar.com> -// -// This document is supplied under the terms of the MIT License, a -// copy of which should be located in the distribution where this -// file was obtained (LICENSE.txt). A copy of the license may also be -// found online at https://opensource.org/licenses/MIT. -// - -== NAME - -nng_ctx - protocol context - -== SYNOPSIS - -[source, c] ----- -#include <nng/nng.h> - -typedef struct nng_ctx_s nng_ctx ----- - -== DESCRIPTION - -An `nng_ctx`(((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, with its various underlying -xref:nng_dialer.5.adoc[dialers], -xref:nng_listener.5.adoc[listeners], -and xref:nng_pipe.5.adoc[pipes], -while still benefiting from separate state tracking. - -For example, a xref:nng_req.7.adoc[_req_] 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. - -IMPORTANT: 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. - -NOTE: 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. - -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. - -(((concurrent)))(((raw mode))) -Historically, applications wanting to use a stateful protocol concurrently -would have to resort to xref:nng.7.adoc#raw_mode[raw mode] 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. - -NOTE: xref:nng.7.adoc#raw_mode[Raw mode] sockets do not support contexts, since -there is generally no state tracked for them, and thus contexts make no sense. - -TIP: Contexts are an excellent mechanism to use when building concurrent -applications, and should be used in lieu of -xref:nng.7.adoc#raw_mode[raw mode] sockets when possible. - -IMPORTANT: Use of file descriptor polling (with descriptors -obtained using the -xref:nng_options.5.adoc#NNG_OPT_RECVFD[`NNG_OPT_RECVFD`] or -xref:nng_options.5.adoc#NNG_OPT_SENDFD[`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. - -[[NNG_CTX_INITIALIZER]] -=== 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 xref:nng_rep.7.adoc[_rep_] service that simply echos messages back -to the sender. - -[source, 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 xref:nng_socket.5.adoc[socket] has already been -created and any transports set up as well with functions such as -xref:nng_dial.3.adoc[`nng_dial()`] -or xref:nng_listen.3.adoc[`nng_listen()`]. - -[source,c] ----- -#define CONCURRENCY 1024 - -static struct 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(&ecs[i].ctx, rep_socket); - nng_aio_alloc(&ecs[i].aio, echo, ecs+i); - ecs[i].state = INIT; - echo(ecs+i); // start it running - } -} ----- - -== SEE ALSO - -[.text-left] -xref:libnng.3.adoc[libnng(3)], -xref:nng_ctx_close.3.adoc[nng_ctx_close(3)], -xref:nng_ctx_open.3.adoc[nng_ctx_open(3)], -xref:nng_ctx_get.3.adoc[nng_ctx_get(3)], -xref:nng_ctx_id.3.adoc[nng_ctx_id(3)], -xref:nng_ctx_recv.3.adoc[nng_ctx_recv(3)], -xref:nng_ctx_recvmsg.3.adoc[nng_ctx_recvmsg(3)], -xref:nng_ctx_send.3.adoc[nng_ctx_send(3)], -xref:nng_ctx_sendmsg.3.adoc[nng_ctx_sendmsg(3)], -xref:nng_ctx_set.3.adoc[nng_ctx_set(3)], -xref:nng_dialer.5.adoc[nng_dialer(5)], -xref:nng_listener.5.adoc[nng_listener(5)], -xref:nng_socket.5.adoc[nng_socket(5)], -xref:nng_options.5.adoc[nng_options(5)], -xref:nng.7.adoc[nng(7)] diff --git a/docs/man/nng_ctx_close.3.adoc b/docs/man/nng_ctx_close.3.adoc deleted file mode 100644 index ff43d0b3..00000000 --- a/docs/man/nng_ctx_close.3.adoc +++ /dev/null @@ -1,54 +0,0 @@ -= nng_ctx_close(3) -// -// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> -// Copyright 2018 Capitar IT Group BV <info@capitar.com> -// -// This document is supplied under the terms of the MIT License, a -// copy of which should be located in the distribution where this -// file was obtained (LICENSE.txt). A copy of the license may also be -// found online at https://opensource.org/licenses/MIT. -// - -== NAME - -nng_ctx_close - close context - -== SYNOPSIS - -[source, 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 xref:nng_socket_close.3.adoc[`nng_socket_close()`]) also closes this context. - -== RETURN VALUES - -This function returns 0 on success, and non-zero otherwise. - -== ERRORS - -[horizontal] -`NNG_ECLOSED`:: The context _ctx_ is already closed or was never opened. - -== SEE ALSO - -[.text-left] -xref:nng_ctx_open.3.adoc[nng_ctx_open(3)], -xref:nng_strerror.3.adoc[nng_strerror(3)], -xref:nng_ctx.5.adoc[nng_ctx(5)], -xref:nng.7.adoc[nng(7)] diff --git a/docs/man/nng_ctx_get.3.adoc b/docs/man/nng_ctx_get.3.adoc deleted file mode 100644 index fa342d2b..00000000 --- a/docs/man/nng_ctx_get.3.adoc +++ /dev/null @@ -1,101 +0,0 @@ -= nng_ctx_get(3) -// -// Copyright 2024 Staysail Systems, Inc. <info@staysail.tech> -// Copyright 2018 Capitar IT Group BV <info@capitar.com> -// -// This document is supplied under the terms of the MIT License, a -// copy of which should be located in the distribution where this -// file was obtained (LICENSE.txt). A copy of the license may also be -// found online at https://opensource.org/licenses/MIT. -// - -== NAME - -nng_ctx_get - get context option - -== SYNOPSIS - -[source, c] ----- -#include <nng/nng.h> - -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_uint64(nng_ctx ctx, const char *opt, uint64_t *u64p); - ----- - -== DESCRIPTION - -(((options, context))) -The `nng_ctx_get` functions are used to retrieve option values for -the xref:nng_ctx.5.adoc[context] _ctx_. -The actual options that may be retrieved in this way vary. -A number of them are documented in xref:nng_options.5.adoc[nng_options(5)]. - -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_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 xref:nng_duration.5.adoc[durations] -(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_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_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 - -[horizontal] -`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 - -[.text-left] -xref:nng_ctx_set.3.adoc[nng_ctx_set(3)], -xref:nng_strdup.3.adoc[nng_strdup(3)], -xref:nng_strerror.3.adoc[nng_strerror(3)], -xref:nng_strfree.3.adoc[nng_strfree(3)], -xref:nng_duration.5.adoc[nng_duration(5)], -xref:nng_ctx.5.adoc[nng_ctx(5)], -xref:nng_options.5.adoc[nng_options(5)], -xref:nng.7.adoc[nng(7)] diff --git a/docs/man/nng_ctx_id.3.adoc b/docs/man/nng_ctx_id.3.adoc deleted file mode 100644 index 51b833a8..00000000 --- a/docs/man/nng_ctx_id.3.adoc +++ /dev/null @@ -1,51 +0,0 @@ -= nng_ctx_id(3) -// -// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> -// Copyright 2018 Capitar IT Group BV <info@capitar.com> -// -// This document is supplied under the terms of the MIT License, a -// copy of which should be located in the distribution where this -// file was obtained (LICENSE.txt). A copy of the license may also be -// found online at https://opensource.org/licenses/MIT. -// - -== NAME - -nng_ctx_id - return numeric context identifier - -== SYNOPSIS - -[source, 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 -xref:nng_ctx_open.3.adoc[`nng_ctx_open()`] function. -Contexts that are allocated on the stack or statically should be -initialized with the macro -xref:nng_ctx.5.adoc#NNG_CTX_INITIALIZER[`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. - -== ERRORS - -None. - -== SEE ALSO - -[.text-left] -xref:nng_ctx.5.adoc[nng_ctx(5)], -xref:nng.7.adoc[nng(7)] diff --git a/docs/man/nng_ctx_open.3.adoc b/docs/man/nng_ctx_open.3.adoc deleted file mode 100644 index 8157c6ee..00000000 --- a/docs/man/nng_ctx_open.3.adoc +++ /dev/null @@ -1,71 +0,0 @@ -= nng_ctx_open(3) -// -// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> -// Copyright 2018 Capitar IT Group BV <info@capitar.com> -// -// This document is supplied under the terms of the MIT License, a -// copy of which should be located in the distribution where this -// file was obtained (LICENSE.txt). A copy of the license may also be -// found online at https://opensource.org/licenses/MIT. -// - -== NAME - -nng_ctx_open - create context - -== SYNOPSIS - -[source,c] ----- -#include <nng/nng.h> - -int nng_ctx_open(nng_ctx *ctxp, nng_socket s); ----- - -== DESCRIPTION - -The `nng_ctx_open()` function creates a separate ((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 xref:nng_rep.7.adoc[_rep_] -socket can each receive requests, and send replies to them, without any -regard to or interference with each other. - -(((raw mode))) -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 -xref:nng.7.adoc#raw_mode[raw mode] sockets. - -NOTE: Use of contexts with xref:nng.7.adoc#raw_mode[raw mode] sockets is -nonsensical, and not supported. - -== RETURN VALUES - -This function returns 0 on success, and non-zero otherwise. - -== ERRORS - -[horizontal] -`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 - -[.text-left] -xref:nng_ctx_close.3.adoc[nng_ctx_close(3)], -xref:nng_ctx_get.3.adoc[nng_ctx_get(3)], -xref:nng_ctx_recv.3.adoc[nng_ctx_recv(3)], -xref:nng_ctx_send.3.adoc[nng_ctx_send(3)], -xref:nng_ctx_set.3.adoc[nng_ctx_set(3)], -xref:nng_strerror.3.adoc[nng_strerror(3)], -xref:nng_ctx.5.adoc[nng_ctx(5)], -xref:nng_socket.5.adoc[nng_socket(5)], -xref:nng_rep.7.adoc[nng_rep(7)], -xref:nng_req.7.adoc[nng_req(7)], -xref:nng.7.adoc[nng(7)] diff --git a/docs/man/nng_ctx_recv.3.adoc b/docs/man/nng_ctx_recv.3.adoc deleted file mode 100644 index bb3d7cf6..00000000 --- a/docs/man/nng_ctx_recv.3.adoc +++ /dev/null @@ -1,74 +0,0 @@ -= nng_ctx_recv(3) -// -// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> -// Copyright 2018 Capitar IT Group BV <info@capitar.com> -// -// This document is supplied under the terms of the MIT License, a -// copy of which should be located in the distribution where this -// file was obtained (LICENSE.txt). A copy of the license may also be -// found online at https://opensource.org/licenses/MIT. -// - -== NAME - -nng_ctx_recv - receive message using context asynchronously - -== SYNOPSIS - -[source, c] ----- -#include <nng/nng.h> - -void nng_ctx_recv(nng_ctx ctx, nng_aio *aio); ----- - -== DESCRIPTION - -The `nng_ctx_recv()` receives a xref:nng_msg.5.adoc[message] using the -xref:nng_ctx.5.adoc[context] _s_ asynchronously. - -When a message is successfully received by the context, it is -stored in the _aio_ by an internal call equivalent to -xref:nng_aio_set_msg.3.adoc[`nng_aio_set_msg()`], then the completion -callback on the _aio_ is executed. -In this case, xref:nng_aio_result.3.adoc[`nng_aio_result()`] 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 xref:nng_aio_result.3.adoc[`nng_aio_result()`] will be non-zero. - -NOTE: The semantics of what receiving a message means varies from protocol to -protocol, so examination of the protocol documentation is encouraged. - -== RETURN VALUES - -None. (The operation completes asynchronously.) - -== ERRORS - -[horizontal] -`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 - -[.text-left] -xref:nng_aio_get_msg.3.adoc[nng_aio_get_msg(3)], -xref:nng_aio_set_msg.3.adoc[nng_aio_set_msg(3)], -xref:nng_msg_alloc.3.adoc[nng_msg_alloc(3)], -xref:nng_strerror.3.adoc[nng_strerror(3)], -xref:nng_aio.5.adoc[nng_aio(5)], -xref:nng_ctx.5.adoc[nng_ctx(5)], -xref:nng_msg.5.adoc[nng_msg(5)], -xref:nng.7.adoc[nng(7)] diff --git a/docs/man/nng_ctx_recvmsg.3.adoc b/docs/man/nng_ctx_recvmsg.3.adoc deleted file mode 100644 index 9651c34c..00000000 --- a/docs/man/nng_ctx_recvmsg.3.adoc +++ /dev/null @@ -1,63 +0,0 @@ -= nng_ctx_recvmsg(3) -// -// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech> -// -// This document is supplied under the terms of the MIT License, a -// copy of which should be located in the distribution where this -// file was obtained (LICENSE.txt). A copy of the license may also be -// found online at https://opensource.org/licenses/MIT. -// - -== NAME - -nng_ctx_recvmsg - receive message using socket - -== SYNOPSIS - -[source, 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. - -NOTE: 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 - -[horizontal] -`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 - -[.text-left] -xref:nng_msg_free.3.adoc[nng_msg_free(3)], -xref:nng_ctx_open.3.adoc[nng_ctx_open(3)], -xref:nng_ctx_recv.3.adoc[nng_ctx_recv(3)], -xref:nng_ctx_sendmsg.3.adoc[nng_ctx_sendmsg(3)], -xref:nng_strerror.3.adoc[nng_strerror(3)], -xref:nng_ctx.5.adoc[nng_ctx(5)], -xref:nng.7.adoc[nng(7)] diff --git a/docs/man/nng_ctx_send.3.adoc b/docs/man/nng_ctx_send.3.adoc deleted file mode 100644 index 8724c1aa..00000000 --- a/docs/man/nng_ctx_send.3.adoc +++ /dev/null @@ -1,88 +0,0 @@ -= nng_ctx_send(3) -// -// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> -// Copyright 2018 Capitar IT Group BV <info@capitar.com> -// -// This document is supplied under the terms of the MIT License, a -// copy of which should be located in the distribution where this -// file was obtained (LICENSE.txt). A copy of the license may also be -// found online at https://opensource.org/licenses/MIT. -// - -== NAME - -nng_ctx_send - send message using context asynchronously - -== SYNOPSIS - -[source, c] ----- -#include <nng/nng.h> - -void nng_ctx_send(nng_ctx ctx, nng_aio *aio); ----- - -== DESCRIPTION - -The `nng_ctx_send()` sends a xref:nng_msg.5.adoc[message] using the -xref:nng_ctx.5.adoc[context] _ctx_ asynchronously. - -The message to send must have previously been set on the _aio_ -using the xref:nng_aio_set_msg.3.adoc[`nng_aio_set_msg()`] 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 xref:nng_aio_result.3.adoc[`nng_aio_result()`] -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 -xref:nng_aio_result.3.adoc[`nng_aio_result()`] will return a non-zero error status. -In this case, the callback has a responsibility to retrieve the message from -the _aio_ with xref:nng_aio_get_msg.3.adoc[`nng_aio_get_msg()`] and dispose of -it appropriately. -(This may include retrying the send operation on the same or a different -socket, or deallocating the message with xref:nng_msg_free.3.adoc[`nng_msg_free()`].) - -NOTE: The semantics of what sending a message means varies from protocol to -protocol, so examination of the protocol documentation is encouraged. - -TIP: Context send operations are asynchronous. -If a synchronous operation is needed, one can be constructed by using a -`NULL` callback on the _aio_ and then waiting for the operation using -xref:nng_aio_wait.3.adoc[`nng_aio_wait()`]. - -== RETURN VALUES - -None. (The operation completes asynchronously.) - -== ERRORS - -[horizontal] -`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 - -[.text-left] -xref:nng_aio_get_msg.3.adoc[nng_aio_get_msg(3)], -xref:nng_aio_set_msg.3.adoc[nng_aio_set_msg(3)], -xref:nng_msg_alloc.3.adoc[nng_msg_alloc(3)], -xref:nng_strerror.3.adoc[nng_strerror(3)], -xref:nng_aio.5.adoc[nng_aio(5)], -xref:nng_ctx.5.adoc[nng_ctx(5)], -xref:nng_msg.5.adoc[nng_msg(5)], -xref:nng.7.adoc[nng(7)] diff --git a/docs/man/nng_ctx_sendmsg.3.adoc b/docs/man/nng_ctx_sendmsg.3.adoc deleted file mode 100644 index 8e2c97f4..00000000 --- a/docs/man/nng_ctx_sendmsg.3.adoc +++ /dev/null @@ -1,84 +0,0 @@ -= nng_ctx_sendmsg(3) -// -// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech> -// -// This document is supplied under the terms of the MIT License, a -// copy of which should be located in the distribution where this -// file was obtained (LICENSE.txt). A copy of the license may also be -// found online at https://opensource.org/licenses/MIT. -// - -== NAME - -nng_ctx_sendmsg - send message using context - -== SYNOPSIS - -[source, 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. - -NOTE: 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 - -[horizontal] -`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 - -[.text-left] -xref:nng_msg_alloc.3.adoc[nng_msg_alloc(3)], -xref:nng_ctx_open.3.adoc[nng_ctx_open(3)], -xref:nng_ctx_recvmsg.3.adoc[nng_ctx_recvmsg(3)], -xref:nng_ctx_send.3.adoc[nng_ctx_send(3)], -xref:nng_sendmsg.3.adoc[nng_sendmsg(3)], -xref:nng_strerror.3.adoc[nng_strerror(3)], -xref:nng_msg.5.adoc[nng_msg(5)], -xref:nng_ctx.5.adoc[nng_ctx(5)], -xref:nng.7.adoc[nng(7)] diff --git a/docs/man/nng_ctx_set.3.adoc b/docs/man/nng_ctx_set.3.adoc deleted file mode 100644 index 95539a63..00000000 --- a/docs/man/nng_ctx_set.3.adoc +++ /dev/null @@ -1,100 +0,0 @@ -= nng_ctx_set(3) -// -// Copyright 2024 Staysail Systems, Inc. <info@staysail.tech> -// Copyright 2018 Capitar IT Group BV <info@capitar.com> -// -// This document is supplied under the terms of the MIT License, a -// copy of which should be located in the distribution where this -// file was obtained (LICENSE.txt). A copy of the license may also be -// found online at https://opensource.org/licenses/MIT. -// - -== NAME - -nng_ctx_set - set context option - -== SYNOPSIS - -[source, c] ----- -#include <nng/nng.h> - -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_uint64(nng_ctx ctx, const char *opt, uint64_t u64); ----- - -== DESCRIPTION - -(((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_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 xref:nng_duration.5.adoc[`nng_duration`]. -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 - -[horizontal] -`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 - -[.text-left] -xref:nng_ctx_get.3.adoc[nng_ctx_get(3)], -xref:nng_socket_set.3.adoc[nng_socket_set(3)], -xref:nng_strerror.3.adoc[nng_strerror(3)], -xref:nng_ctx.5.adoc[nng_ctx(5)], -xref:nng_options.5.adoc[nng_options(5)], -xref:nng_socket.5.adoc[nng_socket(5)], -xref:nng.7.adoc[nng(7)] diff --git a/docs/ref/SUMMARY.md b/docs/ref/SUMMARY.md index 6db29e63..92f24307 100644 --- a/docs/ref/SUMMARY.md +++ b/docs/ref/SUMMARY.md @@ -12,6 +12,8 @@ - [Sockets](./api/sock.md) + - [Contexts](./api/ctx.md) + - [Memory](./api/memory.md) - [Time](./api/time.md) diff --git a/docs/ref/api/ctx.md b/docs/ref/api/ctx.md new file mode 100644 index 00000000..75d1198c --- /dev/null +++ b/docs/ref/api/ctx.md @@ -0,0 +1,261 @@ +# Contexts + +Contexts {{hi:context}} in Scalability Protocols provide for isolation of protocol-specific +state machines and associated data, allowing multiple {{i:concurrent}} {{i:state machines}} (or transactions) +to coexist on a single [socket]. + +For example, a [REP][rep] server may wish to allow many requests to be serviced concurrently, +even though some jobs may take significant time to process. Contexts provide for this ability. + +Not all protocols have contexts, because many protocols simply have no state to manage. +The following protocols support contexts: + +- [REP][rep] +- [REQ][req] +- [RESPONDENT][respondent] +- [SURVEYOR][surveyor] +- [SUB][sub] + +For these protocols, the socket will also have a single, default, context that is used when +performing send or receive operations on the socket directly. + +Other protocols are stateless, at least with respect to message processing, and have no use for +contexts. For the same reason, [raw] mode sockets do not support contexts. + +> [!TIP] +> Developers with experience with [libnanomsg] may be used to using [raw] sockets for concurrency. +> Contexts provide a superior solution, as they are much easier to use, less error prone, and allow +> for easy control of the amount of concurrency used on any given socket. + +One drawback of contexts is that they cannot be used with file descriptor polling using +[`nng_socket_get_recv_poll_fd`] or [`nng_socket_get_send_poll_fd`]. + +## Context Structure + +```c +#define NNG_CTX_INITIALIZER // opaque value + +typedef struct nng_ctx_s nng_ctx; +``` + +The {{i:`nng_ctx`}} structure represents context. This is a handle, and +the members of it are opaque. However, unlike a pointer, it is passed by value. + +A context may be initialized statically with the {{i:`NNG_CTX_INITIALIZER`}} macro, +to ensure that it cannot be confused with a valid open context. + +## Creating a Context + +```c +int nng_ctx_open(nng_ctx *ctxp, nng_socket s); +``` + +The {{i:`nng_ctx_open`}} function creates a separate context to be used with the [socket] _s_, +and returns it at the location pointed by _ctxp_. + +## Context Identity + +```c +int nng_ctx_id(nng_ctx c); +``` + +The {{i:`nng_ctx_id`}} function returns a positive identifier for the context _c_ if it is valid. +Otherwise it returns `-1`. + +A context is considered valid if it was ever opened with [`nng_ctx_open`] 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. + +## Closing a Context + +```c +int nng_ctx_close(nng_ctx ctx); +``` + +The {{i:`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_socket_close`] also closes this context. + +## Sending Messages + +```c +int nng_ctx_sendmsg(nng_ctx ctx, nng_msg *msg, int flags); +void nng_ctx_send(nng_ctx ctx, nng_aio *aio); +``` + +These functions ({{i:`nng_ctx_sendmsg`}} and {{i:`nng_ctx_send`}}) send +messages over the socket _s_. The differences in their behaviors are as follows. + +> [!NOTE] +> The semantics of what sending a message means varies from protocol to +> protocol, so examination of the protocol documentation is encouraged. +> Additionally, some protocols may not support sending at all or may require other pre-conditions first. +> (For example, [REP][rep] sockets cannot normally send data until they have first received a request, +> while [SUB][sub] sockets can only receive data and never send it.) + +### nng_ctx_sendmsg + +The `nng_ctx_sendmsg` function sends the _msg_ over the context _ctx_. + +If this function returns zero, then the socket will dispose of _msg_ when the transmission is complete. +If the function returns a non-zero status, then the call retains the responsibility for disposing of _msg_. + +The _flags_ can contain the value [`NNG_FLAG_NONBLOCK`], indicating that the function should not wait if the socket +cannot accept more data for sending. In such a case, it will return [`NNG_EAGAIN`]. + +### nng_ctx_send + +The `nng_ctx_send` function sends a message asynchronously, using the [`nng_aio`] _aio_, over the context _ctx_. +The message to send must have been set on _aio_ using the [`nng_aio_set_msg`] function. + +If the operation completes successfully, then the context will have disposed of the message. +However, if it fails, then callback of _aio_ should arrange for a final disposition of the message. +(The message can be retrieved from _aio_ with [`nng_aio_get_msg`].) + +Note that callback associated with _aio_ may be called _before_ the message is finally delivered to the recipient. +For example, the message may be sitting in queue, or located in TCP buffers, or even in flight. + +> [!TIP] +> This is the preferred function to use for sending data on a context. While it does require a few extra +> steps on the part of the application, the lowest latencies and highest performance will be achieved by using +> this function instead of [`nng_ctx_sendmsg`]. + +## Receiving Messages + +```c +int nng_ctx_recvmsg(nng_ctx ctx, nng_msg **msgp, int flags); +void nng_ctx_recv(nng_ctx ctx, nng_aio *aio); +``` + +These functions (, {{i:`nng_ctx_recvmsg`}} and {{i:`nng_ctx_recv`}}) receive +messages over the context _ctx_. The differences in their behaviors are as follows. + +> [!NOTE] +> The semantics of what receving a message means varies from protocol to +> protocol, so examination of the protocol documentation is encouraged. +> Additionally, some protocols may not support receiving at all or may require other pre-conditions first. +> (For example, [REQ][req] sockets cannot normally receive data until they have first sent a request.) + +### nng_recvmsg + +The `nng_ctx_recvmsg` function receives a message and stores a pointer to the [`nng_msg`] for that message in _msgp_. + +The _flags_ can contain the value [`NNG_FLAG_NONBLOCK`], indicating that the function should not wait if the socket +has no messages available to receive. In such a case, it will return [`NNG_EAGAIN`]. + +### nng_recv_aio + +The `nng_ctx_send` function receives a message asynchronously, using the [`nng_aio`] _aio_, over the context _ctx_. +On success, the received message can be retrieved from the _aio_ using the [`nng_aio_get_msg`] function. + +> [!NOTE] +> It is important that the application retrieves the message, and disposes of it accordingly. +> Failure to do so will leak the memory. + +> [!TIP] +> This is the preferred function to use for receiving data on a context. While it does require a few extra +> steps on the part of the application, the lowest latencies and highest performance will be achieved by using +> this function instead of [`nng_ctx_recvmsg`]. + +## Context Options + +```c +int nng_ctx_get_bool(nng_ctx ctx, const char *opt, bool *valp); +int nng_ctx_get_int(nng_ctx ctx, const char *opt, int *valp); +int nng_ctx_get_ms(nng_ctx ctx, const char *opt, nng_duration *valp); +int nng_ctx_get_size(nng_ctx ctx, const char *opt, size_t *valp); +int nng_ctx_get_uint64(nng_ctx ctx, const char *opt, uint64_t *valp); + +int nng_ctx_set_bool(nng_ctx ctx, const char *opt, int val); +int nng_ctx_set_int(nng_ctx ctx, const char *opt, int val); +int nng_ctx_set_ms(nng_ctx ctx, const char *opt, nng_duration val); +int nng_ctx_set_size(nng_ctx ctx, const char *opt, size_t val); +int nng_ctx_set_uint64(nng_ctx ctx, const char *opt, uint64_t val); +``` + +These functions are used to retrieve or change the value of an option named _opt_ from the context _ctx_. +The `nng_ctx_get_` functions retrieve the value, and store it in the location _valp_ references. +The `nng_ctx_set_` functions change the value for the _ctx_, taking it from _val_. + +These functions access an option as a specific type. The protocol will have details about which options +are available for contexts, and which type they may be accessed using. + +## Examples + +These examples show building blocks for a concurrent service based on contexts. + +### Example 1: Context Echo Server + +The following program fragment demonstrates the use of contexts to implement +a concurrent [REP][rep] 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; + } +} +``` + +### Example 2: Starting the Echo Service + +Given the above fragment, the following example shows setting up the service. +It assumes that the [socket] has already been +created and any transports set up as well with functions such as [`nng_dial`] or [`nng_listen`]. + +```c + +#define CONCURRENCY 1024 + +static struct 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(&ecs[i].ctx, rep_socket); + nng_aio_alloc(&ecs[i].aio, echo, ecs+i); + ecs[i].state = INIT; + echo(ecs+i); // start it running + } +} +``` + +{{#include ../xref.md}} diff --git a/docs/ref/api/index.md b/docs/ref/api/index.md index 0f20f898..c154ce40 100644 --- a/docs/ref/api/index.md +++ b/docs/ref/api/index.md @@ -17,6 +17,7 @@ include the `nng/nng.h` header file like so: - [Initialization](init.md) - [Messages](msg.md) - [Sockets](sock.md) +- [Contexts](ctx.md) - [Memory](memory.md) - [Time](time.md) - [URLs](url.md) diff --git a/docs/ref/xref.md b/docs/ref/xref.md index 2d98e1d4..16d9938c 100644 --- a/docs/ref/xref.md +++ b/docs/ref/xref.md @@ -225,8 +225,16 @@ [`nng_send`]: /api/sock.md#nng_send [`nng_sendmsg`]: /api/sock.md#nng_sendmsg [`nng_send_aio`]: /api/sock.md#nng_send_aio -[`nng_recv`]: /TODO.md -[`nng_recvmsg`]: /TODO.md +[`nng_recv`]: /api/sock.md#nng_recv +[`nng_recvmsg`]: /api/sock.md#nng_recvmsg +[`nng_recv_aio`]: /api/sock.md#nng_recv_aio +[`nng_ctx_open`]: /api/ctx.md#creating-a-context +[`nng_ctx_id`]: /api/ctx.md#context-identity +[`nng_ctx_close`]: /api/ctx.md#closing-a-context +[`nng_ctx_sendmsg`]: /api/ctx.md#nng_ctx_sendmsg +[`nng_ctx_send`]: /api/ctx.md#nng_ctx_send +[`nng_ctx_recvmsg`]: /api/ctx.md#nng_ctx_recvmsg +[`nng_ctx_recv`]: /api/ctx.md#nng_ctx_recv <!-- Macros --> @@ -291,6 +299,8 @@ [`NNG_OPT_RECVTIMEO`]: /TODO.md [`NNG_OPT_SENDBUF`]: /TODO.md [`NNG_OPT_RECVBUF`]: /TODO.md +[`NNG_SOCKET_INITIALIZER`]: /api/sock.md#socket-structure +[`NNG_CTX_INITIALIZER`]: /api/ctx.md#context-structure <!-- Protocols --> |
