static int qemu_rdma_exchange_send(RDMAContext *rdma, RDMAControlHeader *head,

                                   uint8_t *data, RDMAControlHeader *resp,

                                   int *resp_idx,

                                   int (*callback)(RDMAContext *rdma))

{

    int ret = 0;



    /*

     * Wait until the dest is ready before attempting to deliver the message

     * by waiting for a READY message.

     */

    if (rdma->control_ready_expected) {

        RDMAControlHeader resp;

        ret = qemu_rdma_exchange_get_response(rdma,

                                    &resp, RDMA_CONTROL_READY, RDMA_WRID_READY);

        if (ret < 0) {

            return ret;

        }

    }



    /*

     * If the user is expecting a response, post a WR in anticipation of it.

     */

    if (resp) {

        ret = qemu_rdma_post_recv_control(rdma, RDMA_WRID_DATA);

        if (ret) {

            fprintf(stderr, "rdma migration: error posting"

                    " extra control recv for anticipated result!");

            return ret;

        }

    }



    /*

     * Post a WR to replace the one we just consumed for the READY message.

     */

    ret = qemu_rdma_post_recv_control(rdma, RDMA_WRID_READY);

    if (ret) {

        fprintf(stderr, "rdma migration: error posting first control recv!");

        return ret;

    }



    /*

     * Deliver the control message that was requested.

     */

    ret = qemu_rdma_post_send_control(rdma, data, head);



    if (ret < 0) {

        fprintf(stderr, "Failed to send control buffer!\n");

        return ret;

    }



    /*

     * If we're expecting a response, block and wait for it.

     */

    if (resp) {

        if (callback) {

            DDPRINTF("Issuing callback before receiving response...\n");

            ret = callback(rdma);

            if (ret < 0) {

                return ret;

            }

        }



        DDPRINTF("Waiting for response %s\n", control_desc[resp->type]);

        ret = qemu_rdma_exchange_get_response(rdma, resp,

                                              resp->type, RDMA_WRID_DATA);



        if (ret < 0) {

            return ret;

        }



        qemu_rdma_move_header(rdma, RDMA_WRID_DATA, resp);

        if (resp_idx) {

            *resp_idx = RDMA_WRID_DATA;

        }

        DDPRINTF("Response %s received.\n", control_desc[resp->type]);

    }



    rdma->control_ready_expected = 1;



    return 0;

}

static int qemu_rdma_exchange_send(RDMAContext *rdma, RDMAControlHeader *head,

                                   uint8_t *data, RDMAControlHeader *resp,

                                   int *resp_idx,

                                   int (*callback)(RDMAContext *rdma))

{

    int ret = 0;



    







    if (rdma->control_ready_expected) {

        RDMAControlHeader resp;

        ret = qemu_rdma_exchange_get_response(rdma,

                                    &resp, RDMA_CONTROL_READY, RDMA_WRID_READY);

        if (ret < 0) {

            return ret;

        }

    }



    





    if (resp) {

        ret = qemu_rdma_post_recv_control(rdma, RDMA_WRID_DATA);

        if (ret) {

            fprintf(stderr, "rdma migration: error posting"

                    " extra control recv for anticipated result!");

            return ret;

        }

    }



    





    ret = qemu_rdma_post_recv_control(rdma, RDMA_WRID_READY);

    if (ret) {

        fprintf(stderr, "rdma migration: error posting first control recv!");

        return ret;

    }



    





    ret = qemu_rdma_post_send_control(rdma, data, head);



    if (ret < 0) {

        fprintf(stderr, "Failed to send control buffer!\n");

        return ret;

    }



    





    if (resp) {

        if (callback) {

            DDPRINTF("Issuing callback before receiving response...\n");

            ret = callback(rdma);

            if (ret < 0) {

                return ret;

            }

        }



        DDPRINTF("Waiting for response %s\n", control_desc[resp->type]);

        ret = qemu_rdma_exchange_get_response(rdma, resp,

                                              resp->type, RDMA_WRID_DATA);



        if (ret < 0) {

            return ret;

        }



        qemu_rdma_move_header(rdma, RDMA_WRID_DATA, resp);

        if (resp_idx) {

            *resp_idx = RDMA_WRID_DATA;

        }

        DDPRINTF("Response %s received.\n", control_desc[resp->type]);

    }



    rdma->control_ready_expected = 1;



    return 0;

}

static int FUNC_0(RDMAContext *VAR_6, RDMAControlHeader *VAR_1,

                                   uint8_t *VAR_2, RDMAControlHeader *VAR_3,

                                   int *VAR_4,

                                   int (*VAR_5)(RDMAContext *VAR_6))

{

    int VAR_6 = 0;



    







    if (VAR_6->control_ready_expected) {

        RDMAControlHeader VAR_3;

        VAR_6 = qemu_rdma_exchange_get_response(VAR_6,

                                    &VAR_3, RDMA_CONTROL_READY, RDMA_WRID_READY);

        if (VAR_6 < 0) {

            return VAR_6;

        }

    }



    





    if (VAR_3) {

        VAR_6 = qemu_rdma_post_recv_control(VAR_6, RDMA_WRID_DATA);

        if (VAR_6) {

            fprintf(stderr, "VAR_6 migration: error posting"

                    " extra control recv for anticipated result!");

            return VAR_6;

        }

    }



    





    VAR_6 = qemu_rdma_post_recv_control(VAR_6, RDMA_WRID_READY);

    if (VAR_6) {

        fprintf(stderr, "VAR_6 migration: error posting first control recv!");

        return VAR_6;

    }



    





    VAR_6 = qemu_rdma_post_send_control(VAR_6, VAR_2, VAR_1);



    if (VAR_6 < 0) {

        fprintf(stderr, "Failed to send control buffer!\n");

        return VAR_6;

    }



    





    if (VAR_3) {

        if (VAR_5) {

            DDPRINTF("Issuing VAR_5 before receiving response...\n");

            VAR_6 = VAR_5(VAR_6);

            if (VAR_6 < 0) {

                return VAR_6;

            }

        }



        DDPRINTF("Waiting for response %s\n", control_desc[VAR_3->type]);

        VAR_6 = qemu_rdma_exchange_get_response(VAR_6, VAR_3,

                                              VAR_3->type, RDMA_WRID_DATA);



        if (VAR_6 < 0) {

            return VAR_6;

        }



        qemu_rdma_move_header(VAR_6, RDMA_WRID_DATA, VAR_3);

        if (VAR_4) {

            *VAR_4 = RDMA_WRID_DATA;

        }

        DDPRINTF("Response %s received.\n", control_desc[VAR_3->type]);

    }



    VAR_6->control_ready_expected = 1;



    return 0;

}

static int FUNC_0(RDMAContext *VAR_6, RDMAControlHeader *VAR_1,
uint8_t *VAR_2, RDMAControlHeader *VAR_3,
int *VAR_4,
int (*VAR_5)(RDMAContext *VAR_6))
{ int VAR_6 = 0; if (VAR_6->control_ready_expected) { RDMAControlHeader VAR_3; VAR_6 = qemu_rdma_exchange_get_response(VAR_6,
&VAR_3, RDMA_CONTROL_READY, RDMA_WRID_READY); if (VAR_6 < 0) { return VAR_6; } } if (VAR_3) { VAR_6 = qemu_rdma_post_recv_control(VAR_6, RDMA_WRID_DATA); if (VAR_6) { fprintf(stderr, "VAR_6 migration: error posting"
" extra control recv for anticipated result!"); return VAR_6; } } VAR_6 = qemu_rdma_post_recv_control(VAR_6, RDMA_WRID_READY); if (VAR_6) { fprintf(stderr, "VAR_6 migration: error posting first control recv!"); return VAR_6; } VAR_6 = qemu_rdma_post_send_control(VAR_6, VAR_2, VAR_1); if (VAR_6 < 0) { fprintf(stderr, "Failed to send control buffer!\n"); return VAR_6; } if (VAR_3) { if (VAR_5) { DDPRINTF("Issuing VAR_5 before receiving response...\n"); VAR_6 = VAR_5(VAR_6); if (VAR_6 < 0) { return VAR_6; } } DDPRINTF("Waiting for response %s\n", control_desc[VAR_3->type]); VAR_6 = qemu_rdma_exchange_get_response(VAR_6, VAR_3,
VAR_3->type, RDMA_WRID_DATA); if (VAR_6 < 0) { return VAR_6; } qemu_rdma_move_header(VAR_6, RDMA_WRID_DATA, VAR_3); if (VAR_4) { *VAR_4 = RDMA_WRID_DATA; } DDPRINTF("Response %s received.\n", control_desc[VAR_3->type]); } VAR_6->control_ready_expected = 1; return 0; }