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 need 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, will allow for N:1 mapping
between jsonrpc-monitor and ovsdb-monitor.
Maintaining jsonrpc-monitor pointers in a linked-list is essential
in allowing N:1 mapping. The ovsdb-monitor life cycle
is now reference counted. An empty list means zero references.
Signed-off-by: Andy Zhou <azhou@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
{
json_destroy(m->monitor_id);
hmap_remove(&m->session->monitors, &m->node);
{
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);
struct ovsdb_monitor {
struct ovsdb_replica replica;
struct shash tables; /* Holds "struct ovsdb_monitor_table"s. */
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; /* Contains "jsonrpc_monitor_node"s. */
+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;
/* A particular column being monitored. */
struct ovsdb_monitor_column {
const struct ovsdb_column *column;
+static void ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon);
+
static int
compare_ovsdb_monitor_column(const void *a_, const void *b_)
{
static int
compare_ovsdb_monitor_column(const void *a_, const void *b_)
{
struct ovsdb_jsonrpc_monitor *jsonrpc_monitor)
{
struct ovsdb_monitor *dbmon;
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 = 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);
dbmon->db = db;
shash_init(&dbmon->tables);
+ jm = xzalloc(sizeof *jm);
+ jm->jsonrpc_monitor = jsonrpc_monitor;
+ list_push_back(&dbmon->jsonrpc_monitors, &jm->node);
+
+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);
+
+ /* Destroy ovsdb monitor if this is the last user. */
+ if (list_is_empty(&dbmon->jsonrpc_monitors)) {
+ ovsdb_monitor_destroy(dbmon);
+ }
+
+ return;
+ };
+ }
+
+ /* Should never reach here. jsonrpc_monitor should be on the list. */
+ OVS_NOT_REACHED();
+}
+
+static void
ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon)
{
struct shash_node *node;
ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon)
{
struct shash_node *node;
ovsdb_monitor_destroy_callback(struct ovsdb_replica *replica)
{
struct ovsdb_monitor *dbmon = ovsdb_monitor_cast(replica);
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;
- ovsdb_jsonrpc_monitor_destroy(m);
+ /* 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);
+ }
}
static const struct ovsdb_replica_class ovsdb_jsonrpc_replica_class = {
}
static const struct ovsdb_replica_class ovsdb_jsonrpc_replica_class = {
struct ovsdb_monitor *ovsdb_monitor_create(struct ovsdb *db,
struct ovsdb_jsonrpc_monitor *jsonrpc_monitor);
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);
void ovsdb_monitor_add_table(struct ovsdb_monitor *m,
const struct ovsdb_table *table);
bool ovsdb_monitor_needs_flush(struct ovsdb_monitor *dbmon);
void ovsdb_monitor_get_initial(const 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);