Christine Caulfield wrote:
> This patch adds locking around objdb calls so that they cannot clash
> with a reload or a write operation.
> 
> It also adds notification to the reload operation. Interested parties
> will get a START and an END notification so they can prepare, and/or
> ignore the flurry of update notifications that happen between the two.

Hmmm, it would have helped if I had remembered to pull the updated patch
off my laptop before posting it, sorry.

Actually the only difference between this and the last one is that it
no-longer prevents the update notifications being sent during the reload
process. If people want all those, they should be able to have them.

Chrissie
Index: include/corosync/engine/objdb.h
===================================================================
--- include/corosync/engine/objdb.h	(revision 1670)
+++ include/corosync/engine/objdb.h	(working copy)
@@ -68,6 +68,9 @@
 											void *name_pt, int name_len,
 											void *priv_data_pt);
 
+typedef void (*object_reload_notify_fn_t) (int startstop, int flush,
+											void *priv_data_pt);
+
 struct object_valid {
 	char *object_name;
 	int object_len;
@@ -198,6 +201,7 @@
 		object_key_change_notify_fn_t key_change_notify_fn,
 		object_create_notify_fn_t object_create_notify_fn,
 		object_destroy_notify_fn_t object_destroy_notify_fn,
+		object_reload_notify_fn_t object_reload_notify_fn,
 		void * priv_data_pt);
 
 	void (*object_track_stop) (
Index: exec/objdb.c
===================================================================
--- exec/objdb.c	(revision 1670)
+++ exec/objdb.c	(working copy)
@@ -59,6 +59,7 @@
 	object_key_change_notify_fn_t key_change_notify_fn;
 	object_create_notify_fn_t object_create_notify_fn;
 	object_destroy_notify_fn_t object_destroy_notify_fn;
+	object_reload_notify_fn_t object_reload_notify_fn;
 	struct list_head tracker_list;
 	struct list_head object_list;
 };
@@ -91,6 +92,9 @@
 
 struct objdb_iface_ver0 objdb_iface;
 struct list_head objdb_trackers_head;
+static pthread_rwlock_t reload_lock;
+static pthread_t lock_thread;
+static pthread_mutex_t meta_lock;
 
 static struct hdb_handle_database object_instance_database = {
 	.handle_count	= 0,
@@ -107,6 +111,38 @@
 };
 
 
+static void objdb_wrlock()
+{
+	pthread_mutex_lock(&meta_lock);
+	pthread_rwlock_wrlock(&reload_lock);
+	lock_thread = pthread_self();
+	pthread_mutex_unlock(&meta_lock);
+}
+
+static void objdb_rdlock()
+{
+	pthread_mutex_lock(&meta_lock);
+	if (lock_thread != pthread_self())
+		pthread_rwlock_rdlock(&reload_lock);
+	pthread_mutex_unlock(&meta_lock);
+}
+
+static void objdb_rdunlock()
+{
+	pthread_mutex_lock(&meta_lock);
+	if (lock_thread != pthread_self())
+		pthread_rwlock_unlock(&reload_lock);
+	pthread_mutex_unlock(&meta_lock);
+}
+
+static void objdb_wrunlock()
+{
+	pthread_mutex_lock(&meta_lock);
+	pthread_rwlock_unlock(&reload_lock);
+	lock_thread = 0;
+	pthread_mutex_unlock(&meta_lock);
+}
+
 static int objdb_init (void)
 {
 	unsigned int handle;
@@ -135,6 +171,8 @@
 	list_init (&instance->child_list);
 	list_init (&instance->track_head);
 	list_init (&objdb_trackers_head);
+	pthread_rwlock_init(&reload_lock, NULL);
+	pthread_mutex_init(&meta_lock, NULL);
 
 	hdb_handle_put (&object_instance_database, handle);
 	return (0);
@@ -293,6 +331,30 @@
 	} while (obj_pt->object_handle != OBJECT_PARENT_HANDLE);
 }
 
+static void object_reload_notification(int startstop, int flush)
+{
+	struct list_head * list;
+	struct object_instance * obj_pt;
+	struct object_tracker * tracker_pt;
+	unsigned int res;
+
+	res = hdb_handle_get (&object_instance_database,
+			      OBJECT_PARENT_HANDLE, (void *)&obj_pt);
+
+	for (list = obj_pt->track_head.next;
+	     list != &obj_pt->track_head; list = list->next) {
+
+		tracker_pt = list_entry (list, struct object_tracker, object_list);
+
+		if (tracker_pt->object_reload_notify_fn != NULL) {
+		        tracker_pt->object_reload_notify_fn(startstop, flush,
+							    tracker_pt->data_pt);
+		}
+	}
+	hdb_handle_put (&object_instance_database, OBJECT_PARENT_HANDLE);
+}
+
+
 /*
  * object db create/destroy/set
  */
@@ -308,6 +370,7 @@
 	int found = 0;
 	int i;
 
+	objdb_rdlock();
 	res = hdb_handle_get (&object_instance_database,
 		parent_object_handle, (void *)&parent_instance);
 	if (res != 0) {
@@ -380,7 +443,7 @@
 								object_instance->parent_handle,
 								object_instance->object_name,
 								object_instance->object_name_len);
-
+	objdb_rdunlock();
 	return (0);
 
 error_put_destroy:
@@ -393,6 +456,7 @@
 	hdb_handle_put (&object_instance_database, parent_object_handle);
 
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -403,6 +467,8 @@
 	int res;
 	struct object_instance *object_instance;
 
+	objdb_rdlock();
+
 	res = hdb_handle_get (&object_instance_database,
 		object_handle, (void *)&object_instance);
 	if (res != 0) {
@@ -412,9 +478,11 @@
 	object_instance->priv = priv;
 
 	hdb_handle_put (&object_instance_database, object_handle);
+	objdb_rdunlock();
 	return (0);
 
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -432,6 +500,8 @@
 	int i;
 	unsigned int val;
 
+	objdb_rdlock();
+
 	res = hdb_handle_get (&object_instance_database,
 		object_handle, (void *)&instance);
 	if (res != 0) {
@@ -493,7 +563,7 @@
 	list_add_tail (&object_key->list, &instance->key_head);
 	object_key_changed_notification(object_handle, key_name, key_len,
 								value, value_len, OBJECT_KEY_CREATED);
-
+	objdb_rdunlock();
 	return (0);
 
 error_put_key:
@@ -506,6 +576,7 @@
 	hdb_handle_put (&object_instance_database, object_handle);
 
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -554,9 +625,12 @@
 	struct object_instance *instance;
 	unsigned int res;
 
+	objdb_rdlock();
+
 	res = hdb_handle_get (&object_instance_database,
 		object_handle, (void *)&instance);
 	if (res != 0) {
+		objdb_rdunlock();
 		return (res);
 	}
 
@@ -572,6 +646,7 @@
 	free(instance->object_name);
 	free(instance);
 
+	objdb_rdunlock();
 	return (res);
 }
 
@@ -583,6 +658,7 @@
 	struct object_instance *instance;
 	unsigned int res;
 
+	objdb_rdlock();
 	res = hdb_handle_get (&object_instance_database,
 		object_handle, (void *)&instance);
 	if (res != 0) {
@@ -594,9 +670,11 @@
 
 	hdb_handle_put (&object_instance_database, object_handle);
 
+	objdb_rdunlock();
 	return (0);
 
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -608,6 +686,7 @@
 	struct object_instance *instance;
 	unsigned int res;
 
+	objdb_rdlock();
 	res = hdb_handle_get (&object_instance_database,
 		object_handle, (void *)&instance);
 	if (res != 0) {
@@ -619,9 +698,11 @@
 
 	hdb_handle_put (&object_instance_database, object_handle);
 
+	objdb_rdunlock();
 	return (0);
 
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -638,6 +719,7 @@
 	struct object_instance *object_instance;
 	struct object_find_instance *object_find_instance;
 
+	objdb_rdlock();
 	res = hdb_handle_get (&object_instance_database,
 		object_handle, (void *)&object_instance);
 	if (res != 0) {
@@ -662,6 +744,8 @@
 
 	hdb_handle_put (&object_instance_database, object_handle);
 	hdb_handle_put (&object_find_instance_database, *object_find_handle);
+
+	objdb_rdunlock();
 	return (0);
 
 error_destroy:
@@ -671,6 +755,7 @@
 	hdb_handle_put (&object_instance_database, object_handle);
 
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -684,6 +769,7 @@
 	struct list_head *list;
 	unsigned int found = 0;
 
+	objdb_rdlock();
 	res = hdb_handle_get (&object_find_instance_database,
 		object_find_handle, (void *)&object_find_instance);
 	if (res != 0) {
@@ -714,9 +800,11 @@
 		*object_handle = object_instance->object_handle;
 		res = 0;
 	}
+	objdb_rdunlock();
 	return (res);
 
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -739,6 +827,7 @@
 	struct list_head *list;
 	int found = 0;
 
+	objdb_rdlock();
 	res = hdb_handle_get (&object_instance_database,
 		object_handle, (void *)&instance);
 	if (res != 0) {
@@ -766,9 +855,11 @@
 	}
 
 	hdb_handle_put (&object_instance_database, object_handle);
+	objdb_rdunlock();
 	return (res);
 
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -784,6 +875,7 @@
 	struct list_head *list;
 	int found = 0;
 
+	objdb_rdlock();
 	res = hdb_handle_get (&object_instance_database,
 		object_handle, (void *)&instance);
 	if (res != 0) {
@@ -809,9 +901,11 @@
 	}
 
 	hdb_handle_put (&object_instance_database, object_handle);
+	objdb_rdunlock();
 	return (res);
 
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -827,6 +921,7 @@
 	struct list_head *list;
 	int found = 0;
 
+	objdb_rdlock();
 	res = hdb_handle_get (&object_instance_database,
 		object_handle, (void *)&instance);
 	if (res != 0) {
@@ -852,9 +947,11 @@
 	}
 
 	hdb_handle_put (&object_instance_database, object_handle);
+	objdb_rdunlock();
 	return (res);
 
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -872,6 +969,7 @@
 	struct list_head *list;
 	int found = 0;
 
+	objdb_rdlock();
 	res = hdb_handle_get (&object_instance_database,
 		object_handle, (void *)&instance);
 	if (res != 0) {
@@ -906,9 +1004,11 @@
 	if (ret == 0)
 		object_key_changed_notification(object_handle, key_name, key_len,
 										value, value_len, OBJECT_KEY_DELETED);
+	objdb_rdunlock();
 	return (ret);
 
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -928,6 +1028,8 @@
 	struct list_head *list;
 	int found = 0;
 
+	objdb_rdlock();
+
 	res = hdb_handle_get (&object_instance_database,
 		object_handle, (void *)&instance);
 	if (res != 0) {
@@ -1003,11 +1105,13 @@
 	if (ret == 0)
 		object_key_changed_notification(object_handle, key_name, key_len,
 										new_value, new_value_len, OBJECT_KEY_REPLACED);
+	objdb_rdunlock();
 	return (ret);
 
 error_put:
 	hdb_handle_put (&object_instance_database, object_handle);
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -1018,6 +1122,7 @@
 	int res;
 	struct object_instance *object_instance;
 
+	objdb_rdunlock();
 	res = hdb_handle_get (&object_instance_database,
 		object_handle, (void *)&object_instance);
 	if (res != 0) {
@@ -1027,9 +1132,11 @@
 	*priv = object_instance->priv;
 
 	hdb_handle_put (&object_instance_database, object_handle);
+	objdb_rdunlock();
 	return (0);
 
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -1092,6 +1199,8 @@
 	unsigned int res;
 	struct object_instance *instance;
 
+	objdb_rdlock();
+
 	res = hdb_handle_get (&object_instance_database,
 			      object_handle, (void *)&instance);
 	if (res != 0) {
@@ -1100,9 +1209,11 @@
 	instance->iter_key_list = &instance->key_head;
 
 	hdb_handle_put (&object_instance_database, object_handle);
+	objdb_rdunlock();
 	return (0);
 
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -1119,6 +1230,8 @@
 	struct list_head *list;
 	unsigned int found = 0;
 
+	objdb_rdlock();
+
 	res = hdb_handle_get (&object_instance_database,
 		parent_object_handle, (void *)&instance);
 	if (res != 0) {
@@ -1145,9 +1258,11 @@
 	}
 
 	hdb_handle_put (&object_instance_database, parent_object_handle);
+	objdb_rdunlock();
 	return (res);
 
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -1165,6 +1280,8 @@
 	struct list_head *list;
 	unsigned int found = 0;
 
+	objdb_rdlock();
+
 	res = hdb_handle_get (&object_instance_database,
 		parent_object_handle, (void *)&instance);
 	if (res != 0) {
@@ -1197,9 +1314,11 @@
 	}
 
 	hdb_handle_put (&object_instance_database, parent_object_handle);
+	objdb_rdunlock();
 	return (res);
 
 error_exit:
+	objdb_rdunlock();
 	return (-1);
 }
 
@@ -1210,9 +1329,12 @@
 	struct object_instance *instance;
 	unsigned int res;
 
+	objdb_rdlock();
+
 	res = hdb_handle_get (&object_instance_database,
 			      object_handle, (void *)&instance);
 	if (res != 0) {
+		objdb_rdunlock();
 		return (res);
 	}
 
@@ -1222,6 +1344,7 @@
 		*parent_handle = instance->parent_handle;
 
 	hdb_handle_put (&object_instance_database, object_handle);
+	objdb_rdunlock();
 
 	return (0);
 }
@@ -1233,9 +1356,11 @@
 	struct object_instance *instance;
 	unsigned int res;
 
+	objdb_rdlock();
 	res = hdb_handle_get (&object_instance_database,
 			      object_handle, (void *)&instance);
 	if (res != 0) {
+		objdb_rdunlock();
 		return (res);
 	}
 
@@ -1243,6 +1368,7 @@
 	*object_name_len = instance->object_name_len;
 
 	hdb_handle_put (&object_instance_database, object_handle);
+	objdb_rdunlock();
 
 	return (0);
 }
@@ -1253,6 +1379,7 @@
 							  object_key_change_notify_fn_t key_change_notify_fn,
 							  object_create_notify_fn_t object_create_notify_fn,
 							  object_destroy_notify_fn_t object_destroy_notify_fn,
+			                                  object_reload_notify_fn_t object_reload_notify_fn,
 							  void * priv_data_pt)
 {
 	struct object_instance *instance;
@@ -1271,6 +1398,7 @@
 	tracker_pt->key_change_notify_fn = key_change_notify_fn;
 	tracker_pt->object_create_notify_fn = object_create_notify_fn;
 	tracker_pt->object_destroy_notify_fn = object_destroy_notify_fn;
+	tracker_pt->object_reload_notify_fn = object_reload_notify_fn;
 	tracker_pt->data_pt = priv_data_pt;
 
 	list_init(&tracker_pt->object_list);
@@ -1337,9 +1465,11 @@
 	struct object_instance *instance;
 	unsigned int res;
 
+	objdb_rdlock();
 	res = hdb_handle_get (&object_instance_database,
 			      object_handle, (void *)&instance);
 	if (res != 0) {
+		objdb_rdunlock();
 		return (res);
 	}
 
@@ -1347,6 +1477,7 @@
 
 	hdb_handle_put (&object_instance_database, object_handle);
 
+	objdb_rdunlock();
 	return (res);
 }
 
@@ -1358,13 +1489,19 @@
 	int res;
 
 	main_get_config_modules(&modules, &num_modules);
+
+	objdb_wrlock();
+
 	for (i=0; i<num_modules; i++) {
 		if (modules[i]->config_writeconfig) {
 			res = modules[i]->config_writeconfig(&objdb_iface, error_string);
-			if (res)
+			if (res) {
+				objdb_wrunlock();
 				return res;
+			}
 		}
 	}
+	objdb_wrunlock();
 	return 0;
 }
 
@@ -1376,14 +1513,21 @@
 	int res;
 
 	main_get_config_modules(&modules, &num_modules);
+	object_reload_notification(0, flush);
 
+	objdb_wrlock();
+
 	for (i=0; i<num_modules; i++) {
 		if (modules[i]->config_reloadconfig) {
 			res = modules[i]->config_reloadconfig(&objdb_iface, flush, error_string);
-			if (res)
+			if (res) {
+				objdb_wrunlock();
 				return res;
+			}
 		}
 	}
+	objdb_wrunlock();
+	object_reload_notification(1, flush);
 	return 0;
 }
 
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to