NAME
pmContextConnectTo, pmContextChangeState - connect to a PMCD
C SYNOPSIS
#include <pcp/pmapi.h>
int pmContextConnectTo(int ctx, const struct sockaddr *addr)
int pmContextChangeState(int ctx)
cc ... -lpcp
DESCRIPTION
A host context, created by passing PM_CTXFLAG_SHALLOW to pmNewContext,
must be connected to a source of performance metrics, i.e. pmcd(1), on
some host before it can be used to retrieve data.
The connection process can block for several tens of seconds while
waiting for a reply from either pmcd(1) or from a TCP/IP stack on the
remote host. To avoid blocking, applications which must communicate to
pmcd asynchronously should use these functions to work the state
machine associated with the context creation.
Calling pmContextConnectTo starts the process of establishing
connection to a pmcd(1) on a host identified by the addr. Usually addr
will be an IPv4 socket address, in which case the value of sin_port is
ignored.
Following the call to pmContextConnectTo an application is expected to
wait until the file descriptor associated with the context ctx becomes
ready to accept data, i.e. write(2) is not going to block, then the
application should call pmContextChangeState. If it returns
PM_ERR_AGAIN then the application must wait until data are available on
the file descriptor associated with context ctx and call
pmContextChangeState again until it returns 0 to indicate success or a
negative value to indicate failure.
SEE ALSO
PMAPI(3), pmNewContext(3) and pmGetContextFD(3).
DIAGNOSTICS
PM_ERR_NOCONTEXT
ctx does not identify a valid PMAPI context.
PM_ERR_NOTHOST
The context is not associated with PMCD.
PM_ERR_NOTCONN
The connection to PMCD is not yet established.
PM_ERR_ISCONN
The connection to PMCD is already established.
EXAMPLE
int ctx = pmNewContext(PM_CONTEXT_HOST|PM_CTXFLAG_SHALLOW, "localhost");
int fd = pmGetContextFD(ctx);
struct sockaddr_in sin;
memset (&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if (pmContextConnectTo(ctx, (struct sockaddr *)&sin) >= 0) {
struct pollfd pfd;
pfd.fd = fd;
pfd.events = POLLOUT;
while (1) {
int tout = pmGetContextTimeout(ctx);
if (poll (&pfd, 1, tout) <= 0) {
break;
}
if (pmContextChangeState (ctx) != PM_ERR_AGAIN) {
break;
}
pfd.events = POLLIN;
}
/* We’re now connected and can use the context */
}