= nng_pipe_notify(3)
//
// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2019 Devolutions <info@devolutions.net>
//
// 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_pipe_notify - register pipe notification callback

== SYNOPSIS

[source, c]
----
#include <nng/nng.h>

typedef enum {
        NNG_PIPE_EV_ADD_PRE,
        NNG_PIPE_EV_ADD_POST,
        NNG_PIPE_EV_REM_POST,
} nng_pipe_ev;

typedef void (*nng_pipe_cb)(nng_pipe, nng_pipe_ev, void *);

int nng_pipe_notify(nng_socket s, nng_pipe_ev ev, nng_pipe_cb cb, void *arg);
----

== DESCRIPTION

The `nng_pipe_notify()` function registers the callback function _cb_
to be called whenever a xref:nng_pipe.5.adoc[pipe] the pipe event specified by
_ev_ occurs on the socket _s_.
The callback _cb_ will be passed _arg_ as its final argument.

A different callback may be supplied for each event.
Each event may have at most one callback registered.
Registering a callback implicitly unregisters any previously registered.

The following pipe events are supported:

`NNG_PIPE_EV_ADD_PRE`:: This event occurs after a connection and negotiation
has completed, but before the pipe is added to the socket.
If the pipe is closed (using xref:nng_pipe_close.3.adoc[`nng_pipe_close()`]) at
this point, the socket will never see the pipe, and no further events will
occur for the given pipe.

`NNG_PIPE_EV_ADD_POST`:: This event occurs after the pipe is fully added to
the socket.
Prior to this time, it is not possible to communicate over the pipe with
the socket.

`NNG_PIPE_EV_REM_POST`:: This event occurs after the pipe has been removed
from the socket.
The underlying transport may be closed at this point, and it is not
possible communicate using this pipe.

WARNING: The callback _cb_ function must *not* attempt to perform any
accesses to the socket, as it is called with a lock on the socket held!
Doing so would thus result in a deadlock.

TIP: The callback _cb_ may close a pipe for any reason by simply closing
it using xref:nng_pipe_close.3.adoc[`nng_pipe_close()`].
This might be done before the pipe is added to the socket (during
`NNG_PIPE_EV_ADD_PRE`), for example, if the remote peer is not authorized.

TIP: It is possible to register the same _cb_ and _arg_ for different events
by calling this function separately for different values of _ev_.

NOTE: This function ignores invalid values for _ev_.

== RETURN VALUES

This function returns 0 on success, and non-zero otherwise.

== ERRORS

[horizontal]
`NNG_ECLOSED`:: The socket _s_ does not refer to an open socket.

== SEE ALSO

[.text-left]
xref:nng_pipe_close.3.adoc[nng_pipe_close(3)],
xref:nng_pipe_getopt.3.adoc[nng_pipe_getopt(3)],
xref:nng_pipe.5.adoc[nng_pipe(5)],
xref:nng_socket.5.adoc[nng_socket(5)],
xref:nng.7.adoc[nng(7)]
