static void port_server_accept_done(void * x) {
    AsyncReqInfo * req = (AsyncReqInfo *) x;
    PortServer * server = (PortServer *) req->client_data;

    if (server->sock < 0 || req->error) {
        /* Server closed or fatal error */
        if (server->sock >= 0 && req->error) {
            trace(LOG_ALWAYS, "Port Server accept failed for server %s: %s", server->id, errno_to_str(req->error));
        }
        server->accept_in_progress = 0;
        port_server_shutdown(server);
        return;
    }
    else {
        int fd = req->u.acc.rval;
        set_socket_options(fd); /* set socket options */
        trace (LOG_ALWAYS, "Accept done on server for server %s", server->id);

        /* In auto connect mode, we accept only a single client for the
         * port.
         */
        if (server->auto_connect == 0) {
            port_connection_open(server, fd);
        } else if (server->list == NULL || !server->list->connected || server->list->fd != -1) {
            closesocket(fd);
        } else {
            port_connection_bind(server->list, fd);
        }
    }
    server->accreq.u.acc.addrlen = server->addr_len;
    async_req_post(req);
}
static void event_channel_closed(Channel * c) {
    LINK * qhp = &server_list;
    LINK * qp = qhp->next;

    while (qp != qhp) {
        PortServer * server = link2server(qp);
        qp = qp->next;
        if (server->channel == c) {
            port_server_shutdown(server);
        }
    }
}
示例#3
0
int destroy_port_server(PortServer * server) {
    LINK * qhp = &server_list;
    LINK * qp = qhp->next;
    while (qp != qhp) {
        if (server == (PortServer *)link2server(qp)) break;
        qp = qp->next;
    }
    if (qp == qp->next) {
        errno = EINVAL;
        return -1;
    }
    port_server_shutdown(server);
    return 0;
}
static void port_server_cmd_delete(char * token, Channel * c) {
    char id[256];
    int err = 0;
    PortServer * server;

    json_read_string(&c->inp, id, sizeof(id));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    if ((server = find_port_server(id)) == NULL) err = ERR_INV_CONTEXT;
    else port_server_shutdown(server);
    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);
    write_errno(&c->out, err);
    write_stream(&c->out, MARKER_EOM);
}
static void port_connection_close(PortConnection * conn) {
    PortServer * server = conn->server;
    PortConnection * prev;

    port_connection_unbind(conn);
    if (conn->connected) {
        if (server->disconnect_callback) server->disconnect_callback(server, server->callback_data);
        disconnect_port(conn);
        conn->connected = 0;
        return;
    }

    if (conn->lock_cnt > 0) return;
    if (server->list == conn) server->list = conn->next;
    else {
        prev = server->list;
        while (prev->next != conn)
            prev = prev->next;
        assert (prev->next == conn);
        prev->next = conn->next;
    }
    loc_free(conn);

    /* If the last port connection has been closed and server shutdown is
     * in progress, complete it.
     */
    if (server->list == NULL) {
        if (server->sock == -1) {
            port_server_shutdown(server);
        }
        else if (server->auto_connect) {
            /* Retry target connection */
            post_event_with_delay(port_connection_open_event, server, server->auto_connect_period * 1000000);
        }
    }
}