diff options
Diffstat (limited to 'docs/man/nng_ctx.5.adoc')
| -rw-r--r-- | docs/man/nng_ctx.5.adoc | 176 |
1 files changed, 0 insertions, 176 deletions
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)] |
