pmContextChangeState(3) connect to a PMCD

Other Alias

pmContextConnectTo

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.

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 */
}