Currently, each ovsdb-monitor points to a single jsonrpc_monitor object. This means there is 1:1 relationship between them.
In case multiple jsonrpc-monitors needs to monitor the same tables and the columns within them, then can share a single ovsdb-monitor, so the updates only needs to be maintained once. This patch, with a few following patches is to allow for N:1 mapping between jsonrpc-monitor and ovsdb-monitor. Maintain jsonrpc-monitors pointers in a linked-list is the first step towards allowing N:1 mapping. The ovsdb-monitor life cycle is now reference counted. An empty list means zero references. Signed-off-by: Andy Zhou <az...@nicira.com> --- ovsdb/jsonrpc-server.c | 2 +- ovsdb/ovsdb-monitor.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++---- ovsdb/ovsdb-monitor.h | 5 +++-- 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c index 2437d4b..4eb6f24 100644 --- a/ovsdb/jsonrpc-server.c +++ b/ovsdb/jsonrpc-server.c @@ -1322,6 +1322,6 @@ ovsdb_jsonrpc_monitor_destroy(struct ovsdb_jsonrpc_monitor *m) { json_destroy(m->monitor_id); hmap_remove(&m->session->monitors, &m->node); - ovsdb_monitor_destroy(m->dbmon); + ovsdb_monitor_remove_jsonrpc_monitor(m->dbmon, m); free(m); } diff --git a/ovsdb/ovsdb-monitor.c b/ovsdb/ovsdb-monitor.c index 01a9828..d20593e 100644 --- a/ovsdb/ovsdb-monitor.c +++ b/ovsdb/ovsdb-monitor.c @@ -49,10 +49,15 @@ static const struct ovsdb_replica_class ovsdb_jsonrpc_replica_class; struct ovsdb_monitor { struct ovsdb_replica replica; struct shash tables; /* Holds "struct ovsdb_monitor_table"s. */ - struct ovsdb_jsonrpc_monitor *jsonrpc_monitor; + struct ovs_list jsonrpc_monitors; /* List front end jsonrpc monitors. */ struct ovsdb *db; }; +struct jsonrpc_monitor_node { + struct ovsdb_jsonrpc_monitor *jsonrpc_monitor; + struct ovs_list node; +}; + /* A particular column being monitored. */ struct ovsdb_monitor_column { const struct ovsdb_column *column; @@ -84,6 +89,8 @@ struct ovsdb_monitor_table { struct hmap changes; }; +static void ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon); + static int compare_ovsdb_monitor_column(const void *a_, const void *b_) { @@ -201,15 +208,20 @@ ovsdb_monitor_create(struct ovsdb *db, struct ovsdb_jsonrpc_monitor *jsonrpc_monitor) { struct ovsdb_monitor *dbmon; + struct jsonrpc_monitor_node *jm; dbmon = xzalloc(sizeof *dbmon); ovsdb_replica_init(&dbmon->replica, &ovsdb_jsonrpc_replica_class); ovsdb_add_replica(db, &dbmon->replica); - dbmon->jsonrpc_monitor = jsonrpc_monitor; + list_init(&dbmon->jsonrpc_monitors); dbmon->db = db; shash_init(&dbmon->tables); + jm = xzalloc(sizeof *jm); + jm->jsonrpc_monitor = jsonrpc_monitor; + list_push_back(&dbmon->jsonrpc_monitors, &jm->node); + return dbmon; } @@ -528,6 +540,33 @@ ovsdb_monitor_get_initial(const struct ovsdb_monitor *dbmon) } void +ovsdb_monitor_remove_jsonrpc_monitor(struct ovsdb_monitor *dbmon, + struct ovsdb_jsonrpc_monitor *jsonrpc_monitor) +{ + struct jsonrpc_monitor_node *jm; + + /* Find and remove the jsonrpc monitor from the list. */ + LIST_FOR_EACH(jm, node, &dbmon->jsonrpc_monitors) { + if (jm->jsonrpc_monitor == jsonrpc_monitor) { + list_remove(&jm->node); + free(jm); + + /* If this is the last jsonrpc monitor, also destory + * ovsdb monitor, since there is no other users of + * the monitor. */ + if (list_is_empty(&dbmon->jsonrpc_monitors)) { + ovsdb_monitor_destroy(dbmon); + } + + return; + }; + } + + /* Should never reach here. jsonrpc_monitor should be on the list. */ + ovs_assert(true); +} + +static void ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon) { struct shash_node *node; @@ -569,9 +608,15 @@ static void ovsdb_monitor_destroy_callback(struct ovsdb_replica *replica) { struct ovsdb_monitor *dbmon = ovsdb_monitor_cast(replica); - struct ovsdb_jsonrpc_monitor *m = dbmon->jsonrpc_monitor; + struct jsonrpc_monitor_node *jm, *next; + + /* Delete all front end monitors. Removing the last front + * end monitor will also destroy the corresponding 'ovsdb_monitor'. + * ovsdb monitor will also be destroied. */ + LIST_FOR_EACH_SAFE(jm, next, node, &dbmon->jsonrpc_monitors) { + ovsdb_jsonrpc_monitor_destroy(jm->jsonrpc_monitor); + } - ovsdb_jsonrpc_monitor_destroy(m); } static const struct ovsdb_replica_class ovsdb_jsonrpc_replica_class = { diff --git a/ovsdb/ovsdb-monitor.h b/ovsdb/ovsdb-monitor.h index 6b7f730..829a135 100644 --- a/ovsdb/ovsdb-monitor.h +++ b/ovsdb/ovsdb-monitor.h @@ -30,6 +30,9 @@ enum ovsdb_monitor_selection { struct ovsdb_monitor *ovsdb_monitor_create(struct ovsdb *db, struct ovsdb_jsonrpc_monitor *jsonrpc_monitor); +void ovsdb_monitor_remove_jsonrpc_monitor(struct ovsdb_monitor *dbmon, + struct ovsdb_jsonrpc_monitor *jsonrpc_monitor); + void ovsdb_monitor_add_table(struct ovsdb_monitor *m, const struct ovsdb_table *table); @@ -53,6 +56,4 @@ void ovsdb_monitor_table_set_select(struct ovsdb_monitor *dbmon, bool ovsdb_monitor_needs_flush(struct ovsdb_monitor *dbmon); void ovsdb_monitor_get_initial(const struct ovsdb_monitor *dbmon); - -void ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon); #endif -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev