ivshmem_server_handle_new_conn(IvshmemServer *server)

{

    IvshmemServerPeer *peer, *other_peer;

    struct sockaddr_un unaddr;

    socklen_t unaddr_len;

    int newfd;

    unsigned i;



    /* accept the incoming connection */

    unaddr_len = sizeof(unaddr);

    newfd = qemu_accept(server->sock_fd,

                        (struct sockaddr *)&unaddr, &unaddr_len);



    if (newfd < 0) {

        IVSHMEM_SERVER_DEBUG(server, "cannot accept() %s\n", strerror(errno));

        return -1;

    }



    qemu_set_nonblock(newfd);

    IVSHMEM_SERVER_DEBUG(server, "accept()=%d\n", newfd);



    /* allocate new structure for this peer */

    peer = g_malloc0(sizeof(*peer));

    peer->sock_fd = newfd;



    /* get an unused peer id */

    /* XXX: this could use id allocation such as Linux IDA, or simply

     * a free-list */

    for (i = 0; i < G_MAXUINT16; i++) {

        if (ivshmem_server_search_peer(server, server->cur_id) == NULL) {

            break;

        }

        server->cur_id++;

    }

    if (i == G_MAXUINT16) {

        IVSHMEM_SERVER_DEBUG(server, "cannot allocate new client id\n");

        goto fail;

    }

    peer->id = server->cur_id++;



    /* create eventfd, one per vector */

    peer->vectors_count = server->n_vectors;

    for (i = 0; i < peer->vectors_count; i++) {

        if (event_notifier_init(&peer->vectors[i], FALSE) < 0) {

            IVSHMEM_SERVER_DEBUG(server, "cannot create eventfd\n");

            goto fail;

        }

    }



    /* send peer id and shm fd */

    if (ivshmem_server_send_initial_info(server, peer) < 0) {

        IVSHMEM_SERVER_DEBUG(server, "cannot send initial info\n");

        goto fail;

    }



    /* advertise the new peer to others */

    QTAILQ_FOREACH(other_peer, &server->peer_list, next) {

        for (i = 0; i < peer->vectors_count; i++) {

            ivshmem_server_send_one_msg(other_peer->sock_fd, peer->id,

                                        peer->vectors[i].wfd);

        }

    }



    /* advertise the other peers to the new one */

    QTAILQ_FOREACH(other_peer, &server->peer_list, next) {

        for (i = 0; i < peer->vectors_count; i++) {

            ivshmem_server_send_one_msg(peer->sock_fd, other_peer->id,

                                        other_peer->vectors[i].wfd);

        }

    }



    /* advertise the new peer to itself */

    for (i = 0; i < peer->vectors_count; i++) {

        ivshmem_server_send_one_msg(peer->sock_fd, peer->id,

                                    event_notifier_get_fd(&peer->vectors[i]));

    }



    QTAILQ_INSERT_TAIL(&server->peer_list, peer, next);

    IVSHMEM_SERVER_DEBUG(server, "new peer id = %" PRId64 "\n",

                         peer->id);

    return 0;



fail:

    while (i--) {

        event_notifier_cleanup(&peer->vectors[i]);

    }

    close(newfd);

    g_free(peer);

    return -1;

}

ivshmem_server_handle_new_conn(IvshmemServer *server)

{

    IvshmemServerPeer *peer, *other_peer;

    struct sockaddr_un unaddr;

    socklen_t unaddr_len;

    int newfd;

    unsigned i;



    

    unaddr_len = sizeof(unaddr);

    newfd = qemu_accept(server->sock_fd,

                        (struct sockaddr *)&unaddr, &unaddr_len);



    if (newfd < 0) {

        IVSHMEM_SERVER_DEBUG(server, "cannot accept() %s\n", strerror(errno));

        return -1;

    }



    qemu_set_nonblock(newfd);

    IVSHMEM_SERVER_DEBUG(server, "accept()=%d\n", newfd);



    

    peer = g_malloc0(sizeof(*peer));

    peer->sock_fd = newfd;



    

    



    for (i = 0; i < G_MAXUINT16; i++) {

        if (ivshmem_server_search_peer(server, server->cur_id) == NULL) {

            break;

        }

        server->cur_id++;

    }

    if (i == G_MAXUINT16) {

        IVSHMEM_SERVER_DEBUG(server, "cannot allocate new client id\n");

        goto fail;

    }

    peer->id = server->cur_id++;



    

    peer->vectors_count = server->n_vectors;

    for (i = 0; i < peer->vectors_count; i++) {

        if (event_notifier_init(&peer->vectors[i], FALSE) < 0) {

            IVSHMEM_SERVER_DEBUG(server, "cannot create eventfd\n");

            goto fail;

        }

    }



    

    if (ivshmem_server_send_initial_info(server, peer) < 0) {

        IVSHMEM_SERVER_DEBUG(server, "cannot send initial info\n");

        goto fail;

    }



    

    QTAILQ_FOREACH(other_peer, &server->peer_list, next) {

        for (i = 0; i < peer->vectors_count; i++) {

            ivshmem_server_send_one_msg(other_peer->sock_fd, peer->id,

                                        peer->vectors[i].wfd);

        }

    }



    

    QTAILQ_FOREACH(other_peer, &server->peer_list, next) {

        for (i = 0; i < peer->vectors_count; i++) {

            ivshmem_server_send_one_msg(peer->sock_fd, other_peer->id,

                                        other_peer->vectors[i].wfd);

        }

    }



    

    for (i = 0; i < peer->vectors_count; i++) {

        ivshmem_server_send_one_msg(peer->sock_fd, peer->id,

                                    event_notifier_get_fd(&peer->vectors[i]));

    }



    QTAILQ_INSERT_TAIL(&server->peer_list, peer, next);

    IVSHMEM_SERVER_DEBUG(server, "new peer id = %" PRId64 "\n",

                         peer->id);

    return 0;



fail:

    while (i--) {

        event_notifier_cleanup(&peer->vectors[i]);

    }

    close(newfd);

    g_free(peer);

    return -1;

}

        goto fail;
FUNC_0(IvshmemServer *VAR_0)

{

    IvshmemServerPeer *peer, *other_peer;

    struct sockaddr_un VAR_1;

    socklen_t unaddr_len;

    int VAR_2;

    unsigned VAR_3;



    

    unaddr_len = sizeof(VAR_1);

    VAR_2 = qemu_accept(VAR_0->sock_fd,

                        (struct sockaddr *)&VAR_1, &unaddr_len);



    if (VAR_2 < 0) {

        IVSHMEM_SERVER_DEBUG(VAR_0, "cannot accept() %s\n", strerror(errno));

        return -1;

    }



    qemu_set_nonblock(VAR_2);

    IVSHMEM_SERVER_DEBUG(VAR_0, "accept()=%d\n", VAR_2);



    

    peer = g_malloc0(sizeof(*peer));

    peer->sock_fd = VAR_2;



    

    



    for (VAR_3 = 0; VAR_3 < G_MAXUINT16; VAR_3++) {

        if (ivshmem_server_search_peer(VAR_0, VAR_0->cur_id) == NULL) {

            break;

        }

        VAR_0->cur_id++;

    }

    if (VAR_3 == G_MAXUINT16) {

        IVSHMEM_SERVER_DEBUG(VAR_0, "cannot allocate new client id\n");

        goto fail;

    }

    peer->id = VAR_0->cur_id++;



    

    peer->vectors_count = VAR_0->n_vectors;

    for (VAR_3 = 0; VAR_3 < peer->vectors_count; VAR_3++) {

        if (event_notifier_init(&peer->vectors[VAR_3], FALSE) < 0) {

            IVSHMEM_SERVER_DEBUG(VAR_0, "cannot create eventfd\n");

            goto fail;

        }

    }



    

    if (ivshmem_server_send_initial_info(VAR_0, peer) < 0) {

        IVSHMEM_SERVER_DEBUG(VAR_0, "cannot send initial info\n");

        goto fail;

    }



    

    QTAILQ_FOREACH(other_peer, &VAR_0->peer_list, next) {

        for (VAR_3 = 0; VAR_3 < peer->vectors_count; VAR_3++) {

            ivshmem_server_send_one_msg(other_peer->sock_fd, peer->id,

                                        peer->vectors[VAR_3].wfd);

        }

    }



    

    QTAILQ_FOREACH(other_peer, &VAR_0->peer_list, next) {

        for (VAR_3 = 0; VAR_3 < peer->vectors_count; VAR_3++) {

            ivshmem_server_send_one_msg(peer->sock_fd, other_peer->id,

                                        other_peer->vectors[VAR_3].wfd);

        }

    }



    

    for (VAR_3 = 0; VAR_3 < peer->vectors_count; VAR_3++) {

        ivshmem_server_send_one_msg(peer->sock_fd, peer->id,

                                    event_notifier_get_fd(&peer->vectors[VAR_3]));

    }



    QTAILQ_INSERT_TAIL(&VAR_0->peer_list, peer, next);

    IVSHMEM_SERVER_DEBUG(VAR_0, "new peer id = %" PRId64 "\n",

                         peer->id);

    return 0;



fail:

    while (VAR_3--) {

        event_notifier_cleanup(&peer->vectors[VAR_3]);

    }

    close(VAR_2);

    g_free(peer);

    return -1;

}

FUNC_0(IvshmemServer *VAR_0)
{ IvshmemServerPeer *peer, *other_peer; struct sockaddr_un VAR_1; socklen_t unaddr_len; int VAR_2; unsigned VAR_3; unaddr_len = sizeof(VAR_1); VAR_2 = qemu_accept(VAR_0->sock_fd,
(struct sockaddr *)&VAR_1, &unaddr_len); if (VAR_2 < 0) { IVSHMEM_SERVER_DEBUG(VAR_0, "cannot accept() %s\n", strerror(errno)); return -1; } qemu_set_nonblock(VAR_2); IVSHMEM_SERVER_DEBUG(VAR_0, "accept()=%d\n", VAR_2); peer = g_malloc0(sizeof(*peer)); peer->sock_fd = VAR_2; for (VAR_3 = 0; VAR_3 < G_MAXUINT16; VAR_3++) { if (ivshmem_server_search_peer(VAR_0, VAR_0->cur_id) == NULL) { break; } VAR_0->cur_id++; } if (VAR_3 == G_MAXUINT16) { IVSHMEM_SERVER_DEBUG(VAR_0, "cannot allocate new client id\n"); goto fail; } peer->id = VAR_0->cur_id++; peer->vectors_count = VAR_0->n_vectors; for (VAR_3 = 0; VAR_3 < peer->vectors_count; VAR_3++) { if (event_notifier_init(&peer->vectors[VAR_3], FALSE) < 0) { IVSHMEM_SERVER_DEBUG(VAR_0, "cannot create eventfd\n"); goto fail; } } if (ivshmem_server_send_initial_info(VAR_0, peer) < 0) { IVSHMEM_SERVER_DEBUG(VAR_0, "cannot send initial info\n"); goto fail; } QTAILQ_FOREACH(other_peer, &VAR_0->peer_list, next) { for (VAR_3 = 0; VAR_3 < peer->vectors_count; VAR_3++) { ivshmem_server_send_one_msg(other_peer->sock_fd, peer->id,
peer->vectors[VAR_3].wfd); } } QTAILQ_FOREACH(other_peer, &VAR_0->peer_list, next) { for (VAR_3 = 0; VAR_3 < peer->vectors_count; VAR_3++) { ivshmem_server_send_one_msg(peer->sock_fd, other_peer->id,
other_peer->vectors[VAR_3].wfd); } } for (VAR_3 = 0; VAR_3 < peer->vectors_count; VAR_3++) { ivshmem_server_send_one_msg(peer->sock_fd, peer->id,
event_notifier_get_fd(&peer->vectors[VAR_3])); } QTAILQ_INSERT_TAIL(&VAR_0->peer_list, peer, next); IVSHMEM_SERVER_DEBUG(VAR_0, "new peer id = %" PRId64 "\n",
peer->id); return 0; fail:
while (VAR_3--) { event_notifier_cleanup(&peer->vectors[VAR_3]); } close(VAR_2); g_free(peer); return -1; }