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); } } }
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); } } }