summaryrefslogtreecommitdiffstats
path: root/libnetdata/dictionary
diff options
context:
space:
mode:
Diffstat (limited to 'libnetdata/dictionary')
-rw-r--r--libnetdata/dictionary/dictionary.c27
-rw-r--r--libnetdata/dictionary/dictionary.h6
2 files changed, 28 insertions, 5 deletions
diff --git a/libnetdata/dictionary/dictionary.c b/libnetdata/dictionary/dictionary.c
index 88de7df3af..9d19d5965d 100644
--- a/libnetdata/dictionary/dictionary.c
+++ b/libnetdata/dictionary/dictionary.c
@@ -249,6 +249,9 @@ void dictionary_register_conflict_callback(DICTIONARY *dict, bool (*conflict_cal
if(unlikely(is_view_dictionary(dict)))
fatal("DICTIONARY: called %s() on a view.", __FUNCTION__ );
+ internal_error(!(dict->options & DICT_OPTION_DONT_OVERWRITE_VALUE), "DICTIONARY: registering conflict callback without DICT_OPTION_DONT_OVERWRITE_VALUE");
+ dict->options |= DICT_OPTION_DONT_OVERWRITE_VALUE;
+
dictionary_hooks_allocate(dict);
dict->hooks->conflict_callback = conflict_callback;
dict->hooks->conflict_callback_data = data;
@@ -457,6 +460,10 @@ static inline REFCOUNT DICTIONARY_ITEM_REFCOUNT_GET(DICTIONARY *dict, DICTIONARY
return (REFCOUNT)__atomic_load_n(&item->refcount, __ATOMIC_SEQ_CST);
}
+static inline REFCOUNT DICTIONARY_ITEM_REFCOUNT_GET_SOLE(DICTIONARY_ITEM *item) {
+ return (REFCOUNT)__atomic_load_n(&item->refcount, __ATOMIC_SEQ_CST);
+}
+
// ----------------------------------------------------------------------------
// callbacks execution
@@ -617,6 +624,12 @@ static void ll_recursive_unlock(DICTIONARY *dict, char rw) {
}
}
+void dictionary_write_lock(DICTIONARY *dict) {
+ ll_recursive_lock(dict, DICTIONARY_LOCK_WRITE);
+}
+void dictionary_write_unlock(DICTIONARY *dict) {
+ ll_recursive_unlock(dict, DICTIONARY_LOCK_WRITE);
+}
static inline void dictionary_index_lock_rdlock(DICTIONARY *dict) {
if(unlikely(is_dictionary_single_threaded(dict)))
@@ -1494,7 +1507,9 @@ static bool dictionary_free_all_resources(DICTIONARY *dict, size_t *mem, bool fo
#endif
// destroy the index
+ dictionary_index_lock_wrlock(dict);
index_size += hashtable_destroy_unsafe(dict);
+ dictionary_index_lock_unlock(dict);
ll_recursive_lock(dict, DICTIONARY_LOCK_WRITE);
DICTIONARY_ITEM *item = dict->items.list;
@@ -1797,6 +1812,7 @@ size_t dictionary_destroy(DICTIONARY *dict) {
if(!dict) return 0;
+ dict_flag_set(dict, DICT_FLAG_DESTROYED);
DICTIONARY_STATS_DICT_DESTRUCTIONS_PLUS1(dict);
size_t referenced_items = dictionary_referenced_items(dict);
@@ -1936,20 +1952,23 @@ void dictionary_acquired_item_release(DICTIONARY *dict, DICT_ITEM_CONST DICTIONA
// get the name/value of an item
const char *dictionary_acquired_item_name(DICT_ITEM_CONST DICTIONARY_ITEM *item) {
- api_internal_check(NULL, item, true, false);
return item_get_name(item);
}
void *dictionary_acquired_item_value(DICT_ITEM_CONST DICTIONARY_ITEM *item) {
- // we allow the item to be NULL here
- api_internal_check(NULL, item, true, true);
-
if(likely(item))
return item->shared->value;
return NULL;
}
+size_t dictionary_acquired_item_references(DICT_ITEM_CONST DICTIONARY_ITEM *item) {
+ if(likely(item))
+ return DICTIONARY_ITEM_REFCOUNT_GET_SOLE(item);
+
+ return 0;
+}
+
// ----------------------------------------------------------------------------
// DEL an item
diff --git a/libnetdata/dictionary/dictionary.h b/libnetdata/dictionary/dictionary.h
index 3cbaa87f07..c51746dbff 100644
--- a/libnetdata/dictionary/dictionary.h
+++ b/libnetdata/dictionary/dictionary.h
@@ -180,7 +180,7 @@ extern DICT_ITEM_CONST DICTIONARY_ITEM *dictionary_set_and_acquire_item_advanced
#define dictionary_view_set_and_acquire_item(dict, name, master_item) dictionary_view_set_and_acquire_item_advanced(dict, name, -1, master_item)
extern DICT_ITEM_CONST DICTIONARY_ITEM *dictionary_view_set_and_acquire_item_advanced(DICTIONARY *dict, const char *name, ssize_t name_len, DICTIONARY_ITEM *master_item);
#define dictionary_view_set(dict, name, master_item) dictionary_view_set_advanced(dict, name, -1, master_item)
-extern void *dictionary_view_set_advanced(DICTIONARY *dict, const char *name, ssize_t name_len, DICTIONARY_ITEM *master_item);
+extern void *dictionary_view_set_advanced(DICTIONARY *dict, const char *name, ssize_t name_len, DICT_ITEM_CONST DICTIONARY_ITEM *master_item);
// ----------------------------------------------------------------------------
// Get an item from the dictionary
@@ -211,6 +211,7 @@ extern DICT_ITEM_CONST DICTIONARY_ITEM *dictionary_acquired_item_dup(DICTIONARY
extern const char *dictionary_acquired_item_name(DICT_ITEM_CONST DICTIONARY_ITEM *item);
extern void *dictionary_acquired_item_value(DICT_ITEM_CONST DICTIONARY_ITEM *item);
+extern size_t dictionary_acquired_item_references(DICT_ITEM_CONST DICTIONARY_ITEM *item);
// ----------------------------------------------------------------------------
// Traverse (walk through) the items of the dictionary.
@@ -252,6 +253,9 @@ int dictionary_sorted_walkthrough_rw(DICTIONARY *dict, char rw, int (*callback)(
#define DICTIONARY_LOCK_WRITE 'w'
#define DICTIONARY_LOCK_REENTRANT 'z'
+extern void dictionary_write_lock(DICTIONARY *dict);
+extern void dictionary_write_unlock(DICTIONARY *dict);
+
typedef DICTFE_CONST struct dictionary_foreach {
DICTIONARY *dict; // the dictionary upon we work