<commit_before>/*
 * Copyright (c) 2009, Sun Microsystems, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * - Neither the name of Sun Microsystems, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
/*
 * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
 */

/*
 * clnt_internal.h  Internal client structures needed by some async
 * svc routines
 */

#ifndef _CLNT_INTERNAL_H
#define _CLNT_INTERNAL_H

struct ct_wait_entry
{
    mutex_t mtx;
    cond_t  cv;
};

#include <misc/rbtree_x.h>

typedef struct rpc_dplx_lock
{
    struct ct_wait_entry we;
    int32_t lock_flag_value; /* XXX killme */
    struct {
        char file[32];
        int line;
    } locktrace;
} rpc_dplx_lock_t;


#define MCALL_MSG_SIZE 24

#define CT_NONE                 0x0000
#define CT_EVENTS_BLOCKED       0x0002
#define CT_EPOLL_ACTIVE         0x0004
#define CT_XPRT_DESTROYED       0x0008

/*
 * A client call context.  Intended to enable efficient multiplexing of
 * client calls sharing a client channel.
 */
enum rpc_ctx_state {
    RPC_CTX_START,
    RPC_CTX_REPLY_WAIT,
    RPC_CTX_FINISHED
};

typedef struct rpc_call_ctx {
    struct opr_rbtree_node node_k;
    struct ct_wait_entry we;
    uint32_t xid;
    enum rpc_ctx_state state;
    uint32_t flags;
    struct rpc_msg *msg;
    struct rpc_err error;
    union {
        struct {
            struct __rpc_client *clnt;
            rpcproc_t proc;
            xdrproc_t xdr_args;
            void *args_ptr;
            xdrproc_t xdr_results;
            void *results_ptr;
        } clnt;
        struct {
            /* nothing */
        } svc;
    } ctx_u;
    void *u_data[2]; /* caller user data */
} rpc_ctx_t;

static inline int
call_xid_cmpf(const struct opr_rbtree_node *lhs,
              const struct opr_rbtree_node *rhs)
{
    rpc_ctx_t *lk, *rk;

    lk = opr_containerof(lhs, rpc_ctx_t, node_k);
    rk = opr_containerof(rhs, rpc_ctx_t, node_k);

    if (lk->xid < rk->xid)
        return (-1);

    if (lk->xid == rk->xid)
        return (0);

    return (1);
}

/* unify client private data  */

struct cu_data {
    int cu_fd;          /* connections fd */
    bool cu_closeit; /* opened by library */
    struct sockaddr_storage cu_raddr; /* remote address */
    int cu_rlen;
    struct timeval cu_wait; /* retransmit interval */
    struct timeval cu_total; /* total time for the call */
    struct rpc_err cu_error;
    XDR cu_outxdrs;
    u_int cu_xdrpos;
    u_int cu_sendsz; /* send size */
    u_int cu_recvsz; /* recv size */
    int cu_async;
    int cu_connect; /* Use connect(). */
    int cu_connected; /* Have done connect(). */
    /* formerly, buffers were tacked onto the end */
    char *cu_inbuf;
    char *cu_outbuf;
};

struct ct_data {
    int ct_fd;
    bool ct_closeit; /* close it on destroy */
    struct timeval ct_wait; /* wait interval in milliseconds */
    bool ct_waitset; /* wait set by clnt_control? */
    struct netbuf ct_addr; /* remote addr */
    union {
        char ct_mcallc[MCALL_MSG_SIZE]; /* marshalled callmsg */
        u_int32_t ct_mcalli;
    } ct_u;
    u_int ct_mpos;      /* pos after marshal */
    struct rpc_msg ct_reply; /* async reply */
    struct ct_wait_entry ct_sync; /* wait for completion */
};

enum CX_TYPE
{
    CX_DG_DATA,
    CX_VC_DATA
};

#define X_VC_DATA_FLAG_NONE             0x0000
#define X_VC_DATA_FLAG_CLNT_DESTROYED   0x0001
#define X_VC_DATA_FLAG_SVC_DESTROYED    0x0001

/* new unified state */
struct rpc_dplx_rec
{
    int fd_k;
    mutex_t mtx;
    struct opr_rbtree_node node_k;
    uint32_t refcnt;
    uint32_t flags;
    struct {
        rpc_dplx_lock_t lock;
    } send;
    struct {
        rpc_dplx_lock_t lock;
    } recv;
    struct {
        CLIENT *clnt;
        SVCXPRT *xprt;
    } hdl;
};

struct cx_data
{
    enum CX_TYPE type;
    union {
        struct cu_data cu;
        struct ct_data ct;
    } c_u;
    int cx_fd;                   /* connection's fd */
    struct rpc_dplx_rec *cx_rec; /* unified sync */
};

/* XXX move (file reorg) */
/* kept in xprt->xp_p1, clnt->xp_?? */
struct x_vc_data
{
    uint32_t flags;
    uint32_t refcnt;
    struct rpc_dplx_rec *rec; /* unified sync */
    struct {
        struct ct_data data;
        struct {
            uint32_t xid; /* current xid */
            uint32_t depends_xid;
            struct opr_rbtree t;
        } calls;
    } cx;
    struct {
        enum xprt_stat strm_stat;
        struct timespec last_recv; /* XXX move to shared? */
        int32_t maxrec;
        TAILQ_HEAD(sx_tailq, rpc_msg) msg_q;
        int32_t qlen;
    } sx;
    struct {
        bool nonblock;
        u_int sendsz;
        u_int recvsz;
        XDR xdrs_in;  /* send queue */
        XDR xdrs_out; /* recv queue */
    } shared;
};

#define CU_DATA(cx) (& (cx)->c_u.cu)
#define CT_DATA(cx) (& (cx)->c_u.ct)

/* compartmentalize a bit */
static inline struct x_vc_data *
alloc_x_vc_data(void)
{
    struct x_vc_data *xd = mem_zalloc(sizeof(struct x_vc_data));
    TAILQ_INIT(&xd->sx.msg_q);
    xd->sx.qlen = 0;
    return (xd);
}

static inline void
free_x_vc_data(struct x_vc_data * xd)
{
    mem_free(xd, sizeof(struct x_vc_data));
}

static inline struct cx_data *
alloc_cx_data(enum CX_TYPE type, uint32_t sendsz, uint32_t recvsz)
{
    struct cx_data *cx = mem_zalloc(sizeof(struct cx_data));
    cx->type = type;
    switch (type) {
    case CX_DG_DATA:
        cx->c_u.cu.cu_inbuf = mem_alloc(recvsz);
        cx->c_u.cu.cu_outbuf = mem_alloc(sendsz);
    case CX_VC_DATA:
        break;
    default:
        /* err */
        __warnx(TIRPC_DEBUG_FLAG_MEM,
                "%s: asked to allocate cx_data of unknown type (BUG)",
                __func__);
        break;
    };
    return (cx);
}

static inline void
free_cx_data(struct cx_data *cx)
{
    switch (cx->type) {
    case CX_DG_DATA:
        mem_free(cx->c_u.cu.cu_inbuf, cx->c_u.cu.cu_recvsz);
        mem_free(cx->c_u.cu.cu_outbuf, cx->c_u.cu.cu_sendsz);
    case CX_VC_DATA:
        break;
    default:
        /* err */
        __warnx(TIRPC_DEBUG_FLAG_MEM,
                "%s: asked to free cx_data of unknown type (BUG)",
                __func__);
        break;
    };
    mem_free(cx, sizeof(struct cx_data));
}

void vc_shared_destroy(struct x_vc_data *xd);

#endif /* _CLNT_INTERNAL_H */
<commit_msg>Remove unused rpc_dplx_rec refcnt member.  Minor cleanup.<commit_after>/*
 * Copyright (c) 2009, Sun Microsystems, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * - Neither the name of Sun Microsystems, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
/*
 * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
 */

/*
 * clnt_internal.h  Internal client structures needed by some async
 * svc routines
 */

#ifndef _CLNT_INTERNAL_H
#define _CLNT_INTERNAL_H

struct ct_wait_entry
{
    mutex_t mtx;
    cond_t  cv;
};

#include <misc/rbtree_x.h>

typedef struct rpc_dplx_lock
{
    struct ct_wait_entry we;
    int32_t lock_flag_value; /* XXX killme */
    struct {
        char file[32];
        int line;
    } locktrace;
} rpc_dplx_lock_t;


#define MCALL_MSG_SIZE 24

#define CT_NONE                 0x0000
#define CT_EVENTS_BLOCKED       0x0002
#define CT_EPOLL_ACTIVE         0x0004
#define CT_XPRT_DESTROYED       0x0008

/*
 * A client call context.  Intended to enable efficient multiplexing of
 * client calls sharing a client channel.
 */
enum rpc_ctx_state {
    RPC_CTX_START,
    RPC_CTX_REPLY_WAIT,
    RPC_CTX_FINISHED
};

typedef struct rpc_call_ctx {
    struct opr_rbtree_node node_k;
    struct ct_wait_entry we;
    uint32_t xid;
    enum rpc_ctx_state state;
    uint32_t flags;
    struct rpc_msg *msg;
    struct rpc_err error;
    union {
        struct {
            struct __rpc_client *clnt;
            rpcproc_t proc;
            xdrproc_t xdr_args;
            void *args_ptr;
            xdrproc_t xdr_results;
            void *results_ptr;
        } clnt;
        struct {
            /* nothing */
        } svc;
    } ctx_u;
    void *u_data[2]; /* caller user data */
} rpc_ctx_t;

static inline int
call_xid_cmpf(const struct opr_rbtree_node *lhs,
              const struct opr_rbtree_node *rhs)
{
    rpc_ctx_t *lk, *rk;

    lk = opr_containerof(lhs, rpc_ctx_t, node_k);
    rk = opr_containerof(rhs, rpc_ctx_t, node_k);

    if (lk->xid < rk->xid)
        return (-1);

    if (lk->xid == rk->xid)
        return (0);

    return (1);
}

/* unify client private data  */

struct cu_data {
    int cu_fd;          /* connections fd */
    bool cu_closeit; /* opened by library */
    struct sockaddr_storage cu_raddr; /* remote address */
    int cu_rlen;
    struct timeval cu_wait; /* retransmit interval */
    struct timeval cu_total; /* total time for the call */
    struct rpc_err cu_error;
    XDR cu_outxdrs;
    u_int cu_xdrpos;
    u_int cu_sendsz; /* send size */
    u_int cu_recvsz; /* recv size */
    int cu_async;
    int cu_connect; /* Use connect(). */
    int cu_connected; /* Have done connect(). */
    /* formerly, buffers were tacked onto the end */
    char *cu_inbuf;
    char *cu_outbuf;
};

struct ct_data {
    int ct_fd;
    bool ct_closeit; /* close it on destroy */
    struct timeval ct_wait; /* wait interval in milliseconds */
    bool ct_waitset; /* wait set by clnt_control? */
    struct netbuf ct_addr; /* remote addr */
    union {
        char ct_mcallc[MCALL_MSG_SIZE]; /* marshalled callmsg */
        u_int32_t ct_mcalli;
    } ct_u;
    u_int ct_mpos;      /* pos after marshal */
    struct rpc_msg ct_reply; /* async reply */
    struct ct_wait_entry ct_sync; /* wait for completion */
};

enum CX_TYPE
{
    CX_DG_DATA,
    CX_VC_DATA
};

#define X_VC_DATA_FLAG_NONE             0x0000
#define X_VC_DATA_FLAG_CLNT_DESTROYED   0x0001
#define X_VC_DATA_FLAG_SVC_DESTROYED    0x0001

/* new unified state */
struct rpc_dplx_rec
{
    int fd_k;
    mutex_t mtx;
    struct opr_rbtree_node node_k;
    uint32_t refcnt;
    struct {
        rpc_dplx_lock_t lock;
    } send;
    struct {
        rpc_dplx_lock_t lock;
    } recv;
    struct {
        CLIENT *clnt;
        SVCXPRT *xprt;
    } hdl;
};

struct cx_data
{
    enum CX_TYPE type;
    union {
        struct cu_data cu;
        struct ct_data ct;
    } c_u;
    int cx_fd; /* connection's fd */
    struct rpc_dplx_rec *cx_rec; /* unified sync */
};

struct x_vc_data
{
    uint32_t flags;
    uint32_t refcnt;
    struct rpc_dplx_rec *rec; /* unified sync */
    struct {
        struct ct_data data;
        struct {
            uint32_t xid; /* current xid */
            uint32_t depends_xid;
            struct opr_rbtree t;
        } calls;
    } cx;
    struct {
        enum xprt_stat strm_stat;
        struct timespec last_recv; /* XXX move to shared? */
        int32_t maxrec;
        TAILQ_HEAD(sx_tailq, rpc_msg) msg_q;
        int32_t qlen;
    } sx;
    struct {
        bool nonblock;
        u_int sendsz;
        u_int recvsz;
        XDR xdrs_in;  /* send queue */
        XDR xdrs_out; /* recv queue */
    } shared;
};

#define CU_DATA(cx) (& (cx)->c_u.cu)
#define CT_DATA(cx) (& (cx)->c_u.ct)

/* compartmentalize a bit */
static inline struct x_vc_data *
alloc_x_vc_data(void)
{
    struct x_vc_data *xd = mem_zalloc(sizeof(struct x_vc_data));
    TAILQ_INIT(&xd->sx.msg_q);
    xd->sx.qlen = 0;
    return (xd);
}

static inline void
free_x_vc_data(struct x_vc_data * xd)
{
    mem_free(xd, sizeof(struct x_vc_data));
}

static inline struct cx_data *
alloc_cx_data(enum CX_TYPE type, uint32_t sendsz, uint32_t recvsz)
{
    struct cx_data *cx = mem_zalloc(sizeof(struct cx_data));
    cx->type = type;
    switch (type) {
    case CX_DG_DATA:
        cx->c_u.cu.cu_inbuf = mem_alloc(recvsz);
        cx->c_u.cu.cu_outbuf = mem_alloc(sendsz);
    case CX_VC_DATA:
        break;
    default:
        /* err */
        __warnx(TIRPC_DEBUG_FLAG_MEM,
                "%s: asked to allocate cx_data of unknown type (BUG)",
                __func__);
        break;
    };
    return (cx);
}

static inline void
free_cx_data(struct cx_data *cx)
{
    switch (cx->type) {
    case CX_DG_DATA:
        mem_free(cx->c_u.cu.cu_inbuf, cx->c_u.cu.cu_recvsz);
        mem_free(cx->c_u.cu.cu_outbuf, cx->c_u.cu.cu_sendsz);
    case CX_VC_DATA:
        break;
    default:
        /* err */
        __warnx(TIRPC_DEBUG_FLAG_MEM,
                "%s: asked to free cx_data of unknown type (BUG)",
                __func__);
        break;
    };
    mem_free(cx, sizeof(struct cx_data));
}

void vc_shared_destroy(struct x_vc_data *xd);

#endif /* _CLNT_INTERNAL_H */

{'fraction_non_alphanumeric': 0.08770668583752696, 'fraction_numerical': 0.010914319325534279, 'mean_word_length': 2.5503480278422272, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4511477', 'n_tokens_mistral': 5580, 'n_tokens_neox': 5238, 'n_words': 1526}