[ovs-dev] [poll group RFC 6/6] ovsdb: Change jsonrpc server to make use of poll group
Andy Zhou
azhou at ovn.org
Fri Feb 19 04:20:56 UTC 2016
When enabled, jsonrpc server creates a poll group for all jsonrpc
sessions it created.
Signed-off-by: Andy Zhou <azhou at ovn.org>
---
ovsdb/jsonrpc-server.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 62 insertions(+), 5 deletions(-)
diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c
index 53a982b..810b7cd 100644
--- a/ovsdb/jsonrpc-server.c
+++ b/ovsdb/jsonrpc-server.c
@@ -28,6 +28,7 @@
#include "ovsdb-error.h"
#include "ovsdb-parser.h"
#include "ovsdb.h"
+#include "poll-group.h"
#include "poll-loop.h"
#include "reconnect.h"
#include "row.h"
@@ -103,8 +104,11 @@ struct ovsdb_jsonrpc_server {
struct ovsdb_server up;
unsigned int n_sessions;
struct shash remotes; /* Contains "struct ovsdb_jsonrpc_remote *"s. */
+ struct poll_group *poll_group; /* group poll jsonrpc sessions. */
};
+static void ovsdb_jsonrpc_server_run_poll_group(struct poll_group *);
+
/* A configured remote. This is either a passive stream listener plus a list
* of the currently connected sessions, or a list of exactly one active
* session. */
@@ -131,11 +135,17 @@ static void ovsdb_jsonrpc_server_del_remote(struct shash_node *);
* To disable it, set 'disable_epoll to false.
*/
struct ovsdb_jsonrpc_server *
-ovsdb_jsonrpc_server_create(bool disable_epoll OVS_UNUSED)
+ovsdb_jsonrpc_server_create(bool disable_epoll)
{
struct ovsdb_jsonrpc_server *server = xzalloc(sizeof *server);
+ struct poll_group *poll_group = NULL;
+
ovsdb_server_init(&server->up);
shash_init(&server->remotes);
+ if (!disable_epoll) {
+ poll_group = poll_group_create("jsonrpc-sessions-pg");
+ }
+ server->poll_group = poll_group;
return server;
}
@@ -323,6 +333,7 @@ void
ovsdb_jsonrpc_server_run(struct ovsdb_jsonrpc_server *svr)
{
struct shash_node *node;
+ struct poll_group *poll_group = svr->poll_group;
SHASH_FOR_EACH (node, &svr->remotes) {
struct ovsdb_jsonrpc_remote *remote = node->data;
@@ -334,10 +345,13 @@ ovsdb_jsonrpc_server_run(struct ovsdb_jsonrpc_server *svr)
error = pstream_accept(remote->listener, &stream);
if (!error) {
struct jsonrpc_session *js;
+ struct ovsdb_jsonrpc_session *ovsdb_js;
js = jsonrpc_session_open_unreliably(jsonrpc_open(stream),
remote->dscp);
- ovsdb_jsonrpc_session_create(remote, js);
- } else if (error != EAGAIN) {
+ ovsdb_js = ovsdb_jsonrpc_session_create(remote, js);
+ stream_join(stream, svr->poll_group, ovsdb_js);
+ }
+ else if (error != EAGAIN) {
VLOG_WARN_RL(&rl, "%s: accept failed: %s",
pstream_get_name(remote->listener),
ovs_strerror(error));
@@ -346,11 +360,16 @@ ovsdb_jsonrpc_server_run(struct ovsdb_jsonrpc_server *svr)
ovsdb_jsonrpc_session_run_all(remote);
}
+
+ if (poll_group) {
+ ovsdb_jsonrpc_server_run_poll_group(poll_group);
+ }
}
void
ovsdb_jsonrpc_server_wait(struct ovsdb_jsonrpc_server *svr)
{
+ struct poll_group *poll_group = svr->poll_group;
struct shash_node *node;
SHASH_FOR_EACH (node, &svr->remotes) {
@@ -362,6 +381,7 @@ ovsdb_jsonrpc_server_wait(struct ovsdb_jsonrpc_server *svr)
ovsdb_jsonrpc_session_wait_all(remote);
}
+ poll_group_poll_wait(poll_group);
}
/* Adds some memory usage statistics for 'svr' into 'usage', for use with
@@ -496,6 +516,26 @@ ovsdb_jsonrpc_session_run_all(struct ovsdb_jsonrpc_remote *remote)
struct ovsdb_jsonrpc_session *s, *next;
LIST_FOR_EACH_SAFE (s, next, node, &remote->sessions) {
+ if (!jsonrpc_session_joined_poll_group(s->js)) {
+ int error = ovsdb_jsonrpc_session_run(s);
+ if (error) {
+ ovsdb_jsonrpc_session_close(s);
+ }
+ }
+ }
+}
+
+static void
+ovsdb_jsonrpc_server_run_poll_group(struct poll_group *group)
+{
+ void **sessions;
+ size_t n, i;
+
+ poll_group_get_events(group, &sessions, &n);
+
+ for (i = 0; i < n; i++) {
+ struct ovsdb_jsonrpc_session *s;
+ s = sessions[i];
int error = ovsdb_jsonrpc_session_run(s);
if (error) {
ovsdb_jsonrpc_session_close(s);
@@ -504,9 +544,19 @@ ovsdb_jsonrpc_session_run_all(struct ovsdb_jsonrpc_remote *remote)
}
static void
+ovsdb_jsonrpc_session_poll_group_update(struct ovsdb_jsonrpc_session *s)
+{
+ if (ovsdb_jsonrpc_monitor_needs_flush(s) ||
+ jsonrpc_session_get_backlog(s->js) ||
+ jsonrpc_session_has_pending_input(s->js)) {
+
+ jsonrpc_session_poll_group_update(s->js, true);
+ }
+}
+
+static void
ovsdb_jsonrpc_session_wait(struct ovsdb_jsonrpc_session *s)
{
- jsonrpc_session_wait(s->js);
if (!jsonrpc_session_get_backlog(s->js)) {
if (ovsdb_jsonrpc_monitor_needs_flush(s)) {
poll_immediate_wake();
@@ -522,7 +572,14 @@ ovsdb_jsonrpc_session_wait_all(struct ovsdb_jsonrpc_remote *remote)
struct ovsdb_jsonrpc_session *s;
LIST_FOR_EACH (s, node, &remote->sessions) {
- ovsdb_jsonrpc_session_wait(s);
+ jsonrpc_session_wait(s->js);
+
+ bool update_pg = jsonrpc_session_joined_poll_group(s->js);
+ if (update_pg) {
+ ovsdb_jsonrpc_session_poll_group_update(s);
+ } else {
+ ovsdb_jsonrpc_session_wait(s);
+ }
}
}
--
1.9.1
More information about the dev
mailing list