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.
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 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);
@@ -191,6 +229,9 @@
unsigned int obj_handle = object_handle;
unsigned int res;
+ if (lock_thread)
+ return;
+
do {
res = hdb_handle_get (&object_instance_database,
obj_handle, (void *)&obj_pt);
@@ -226,6 +267,9 @@
unsigned int obj_handle = object_handle;
unsigned int res;
+ if (lock_thread)
+ return;
+
do {
res = hdb_handle_get (&object_instance_database,
obj_handle, (void *)&obj_pt);
@@ -266,6 +310,9 @@
unsigned int obj_handle = object_handle;
unsigned int res;
+ if (lock_thread)
+ return;
+
do {
res = hdb_handle_get (&object_instance_database,
obj_handle, (void *)&obj_pt);
@@ -293,6 +340,30 @@
} while (obj_pt->object_handle != OBJECT_PARENT_HANDLE);
}
+static void object_reload_notification(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(flush,
+ tracker_pt->data_pt);
+ }
+ }
+ hdb_handle_put (&object_instance_database, OBJECT_PARENT_HANDLE);
+}
+
+
/*
* object db create/destroy/set
*/
@@ -308,6 +379,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 +452,7 @@
object_instance->parent_handle,
object_instance->object_name,
object_instance->object_name_len);
-
+ objdb_rdunlock();
return (0);
error_put_destroy:
@@ -393,6 +465,7 @@
hdb_handle_put (&object_instance_database, parent_object_handle);
error_exit:
+ objdb_rdunlock();
return (-1);
}
@@ -403,6 +476,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 +487,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 +509,8 @@
int i;
unsigned int val;
+ objdb_rdlock();
+
res = hdb_handle_get (&object_instance_database,
object_handle, (void *)&instance);
if (res != 0) {
@@ -493,7 +572,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 +585,7 @@
hdb_handle_put (&object_instance_database, object_handle);
error_exit:
+ objdb_rdunlock();
return (-1);
}
@@ -554,9 +634,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 +655,7 @@
free(instance->object_name);
free(instance);
+ objdb_rdunlock();
return (res);
}
@@ -583,6 +667,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 +679,11 @@
hdb_handle_put (&object_instance_database, object_handle);
+ objdb_rdunlock();
return (0);
error_exit:
+ objdb_rdunlock();
return (-1);
}
@@ -608,6 +695,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 +707,11 @@
hdb_handle_put (&object_instance_database, object_handle);
+ objdb_rdunlock();
return (0);
error_exit:
+ objdb_rdunlock();
return (-1);
}
@@ -638,6 +728,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 +753,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 +764,7 @@
hdb_handle_put (&object_instance_database, object_handle);
error_exit:
+ objdb_rdunlock();
return (-1);
}
@@ -684,6 +778,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 +809,11 @@
*object_handle = object_instance->object_handle;
res = 0;
}
+ objdb_rdunlock();
return (res);
error_exit:
+ objdb_rdunlock();
return (-1);
}
@@ -739,6 +836,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 +864,11 @@
}
hdb_handle_put (&object_instance_database, object_handle);
+ objdb_rdunlock();
return (res);
error_exit:
+ objdb_rdunlock();
return (-1);
}
@@ -784,6 +884,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 +910,11 @@
}
hdb_handle_put (&object_instance_database, object_handle);
+ objdb_rdunlock();
return (res);
error_exit:
+ objdb_rdunlock();
return (-1);
}
@@ -827,6 +930,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 +956,11 @@
}
hdb_handle_put (&object_instance_database, object_handle);
+ objdb_rdunlock();
return (res);
error_exit:
+ objdb_rdunlock();
return (-1);
}
@@ -872,6 +978,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 +1013,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 +1037,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 +1114,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 +1131,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 +1141,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 +1208,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 +1218,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 +1239,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 +1267,11 @@
}
hdb_handle_put (&object_instance_database, parent_object_handle);
+ objdb_rdunlock();
return (res);
error_exit:
+ objdb_rdunlock();
return (-1);
}
@@ -1165,6 +1289,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 +1323,11 @@
}
hdb_handle_put (&object_instance_database, parent_object_handle);
+ objdb_rdunlock();
return (res);
error_exit:
+ objdb_rdunlock();
return (-1);
}
@@ -1210,9 +1338,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 +1353,7 @@
*parent_handle = instance->parent_handle;
hdb_handle_put (&object_instance_database, object_handle);
+ objdb_rdunlock();
return (0);
}
@@ -1233,9 +1365,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 +1377,7 @@
*object_name_len = instance->object_name_len;
hdb_handle_put (&object_instance_database, object_handle);
+ objdb_rdunlock();
return (0);
}
@@ -1253,6 +1388,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 +1407,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 +1474,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 +1486,7 @@
hdb_handle_put (&object_instance_database, object_handle);
+ objdb_rdunlock();
return (res);
}
@@ -1358,13 +1498,20 @@
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;
+ }
}
}
+ lock_thread = 0;
+ objdb_wrunlock();
return 0;
}
@@ -1377,13 +1524,19 @@
main_get_config_modules(&modules, &num_modules);
+ 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;
+ }
}
}
+ object_reload_notification(flush);
+ objdb_wrunlock();
return 0;
}
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais