void jsonrpc_session_wait(struct jsonrpc_session *s) { if (s->rpc) { jsonrpc_wait(s->rpc); } else if (s->stream) { stream_run_wait(s->stream); stream_connect_wait(s->stream); } if (s->pstream) { pstream_wait(s->pstream); } reconnect_wait(s->reconnect, time_msec()); }
static void do_listen(struct ovs_cmdl_context *ctx) { struct pstream *pstream; struct jsonrpc **rpcs; size_t n_rpcs, allocated_rpcs; bool done; int error; error = jsonrpc_pstream_open(ctx->argv[1], &pstream, DSCP_DEFAULT); if (error) { ovs_fatal(error, "could not listen on \"%s\"", ctx->argv[1]); } daemonize(); rpcs = NULL; n_rpcs = allocated_rpcs = 0; done = false; for (;;) { struct stream *stream; size_t i; /* Accept new connections. */ error = pstream_accept(pstream, &stream); if (!error) { if (n_rpcs >= allocated_rpcs) { rpcs = x2nrealloc(rpcs, &allocated_rpcs, sizeof *rpcs); } rpcs[n_rpcs++] = jsonrpc_open(stream); } else if (error != EAGAIN) { ovs_fatal(error, "pstream_accept failed"); } /* Service existing connections. */ for (i = 0; i < n_rpcs; ) { struct jsonrpc *rpc = rpcs[i]; struct jsonrpc_msg *msg; jsonrpc_run(rpc); if (!jsonrpc_get_backlog(rpc)) { error = jsonrpc_recv(rpc, &msg); if (!error) { error = handle_rpc(rpc, msg, &done); jsonrpc_msg_destroy(msg); } else if (error == EAGAIN) { error = 0; } } if (!error) { error = jsonrpc_get_status(rpc); } if (error) { jsonrpc_close(rpc); ovs_error(error, "connection closed"); memmove(&rpcs[i], &rpcs[i + 1], (n_rpcs - i - 1) * sizeof *rpcs); n_rpcs--; } else { i++; } } /* Wait for something to do. */ if (done && !n_rpcs) { break; } pstream_wait(pstream); for (i = 0; i < n_rpcs; i++) { struct jsonrpc *rpc = rpcs[i]; jsonrpc_wait(rpc); if (!jsonrpc_get_backlog(rpc)) { jsonrpc_recv_wait(rpc); } } poll_block(); } free(rpcs); pstream_close(pstream); }