else return strcmp(((struct config_value *)a)->name, ((struct config_value *)b)->name);
}
-#define config_value_index_add(co, cv) avl_insert_lock(&((co)->values_index), (avl *)(cv))
-#define config_value_index_del(co, cv) avl_remove_lock(&((co)->values_index), (avl *)(cv))
+#define config_value_index_add(co, cv) (struct config_value *)avl_insert_lock(&((co)->values_index), (avl *)(cv))
+#define config_value_index_del(co, cv) (struct config_value *)avl_remove_lock(&((co)->values_index), (avl *)(cv))
static struct config_value *config_value_index_find(struct config *co, const char *name, uint32_t hash) {
struct config_value tmp;
AVL_LOCK_INITIALIZER
};
-#define config_index_add(cfg) avl_insert_lock(&config_root_index, (avl *)(cfg))
-#define config_index_del(cfg) avl_remove_lock(&config_root_index, (avl *)(cfg))
+#define config_index_add(cfg) (struct config *)avl_insert_lock(&config_root_index, (avl *)(cfg))
+#define config_index_del(cfg) (struct config *)avl_remove_lock(&config_root_index, (avl *)(cfg))
static struct config *config_index_find(const char *name, uint32_t hash) {
struct config tmp;
avl_init_lock(&co->values_index, config_value_compare);
- config_index_add(co);
+ if(unlikely(config_index_add(co) != co))
+ error("INTERNAL ERROR: indexing of section '%s', already exists.", co->name);
config_global_write_lock();
struct config *co2 = config_root;
cv->hash = simple_hash(cv->name);
cv->value = strdupz(value);
- config_value_index_add(co, cv);
+ if(unlikely(config_value_index_add(co, cv) != cv))
+ error("INTERNAL ERROR: indexing of config '%s' in section '%s': already exists.", cv->name, co->name);
config_section_write_lock(co);
struct config_value *cv2 = co->values;
cv2 = config_value_index_find(co, new, 0);
if(cv2) goto cleanup;
- config_value_index_del(co, cv);
+ if(unlikely(config_value_index_del(co, cv) != cv))
+ error("INTERNAL ERROR: deletion of config '%s' from section '%s', deleted tge wrong config entry.", cv->name, co->name);
freez(cv->name);
cv->name = strdupz(new);
-
cv->hash = simple_hash(cv->name);
+ if(unlikely(config_value_index_add(co, cv) != cv))
+ error("INTERNAL ERROR: indexing of config '%s' in section '%s', already exists.", cv->name, co->name);
- config_value_index_add(co, cv);
config_section_unlock(co);
return 0;
if(unlikely(debug))
fprintf(stderr, "apps.plugin: >> slot %d is empty.\n", id);
- file_descriptor_remove(&all_files[id]);
+ if(unlikely(file_descriptor_remove(&all_files[id]) != (void *)&all_files[id]))
+ error("INTERNAL ERROR: removal of unused fd from index, removed a different fd");
+
#ifdef NETDATA_INTERNAL_CHECKS
all_files[id].magic = 0x00000000;
#endif /* NETDATA_INTERNAL_CHECKS */
all_files_index.root = NULL;
for(i = 0; i < all_files_size; i++) {
if(!all_files[i].count) continue;
- file_descriptor_add(&all_files[i]);
+ if(unlikely(file_descriptor_add(&all_files[i]) != (void *)&all_files[i]))
+ error("INTERNAL ERROR: duplicate indexing of fd during realloc.");
}
if(unlikely(debug))
#ifdef NETDATA_INTERNAL_CHECKS
all_files[c].magic = 0x0BADCAFE;
#endif /* NETDATA_INTERNAL_CHECKS */
- file_descriptor_add(&all_files[c]);
+ if(unlikely(file_descriptor_add(&all_files[c]) != (void *)&all_files[c]))
+ error("INTERNAL ERROR: duplicate indexing of fd.");
if(unlikely(debug))
fprintf(stderr, "apps.plugin: using fd position %d (name: %s)\n", c, all_files[c].name);
* a is linked directly to the tree, so it has to
* be properly allocated by the caller.
*/
-avl *avl_insert_lock(avl_tree_lock *t, avl *a) __attribute__((returns_nonnull));
-avl *avl_insert(avl_tree *t, avl *a) __attribute__((returns_nonnull));
+avl *avl_insert_lock(avl_tree_lock *t, avl *a) __attribute__((returns_nonnull, warn_unused_result));
+avl *avl_insert(avl_tree *t, avl *a) __attribute__((returns_nonnull, warn_unused_result));
/* Remove an element a from the AVL tree t
* returns a pointer to the removed element
* or NULL if an element equal to a is not found
* (equal as returned by t->compar())
*/
-avl *avl_remove_lock(avl_tree_lock *t, avl *a);
-avl *avl_remove(avl_tree *t, avl *a);
+avl *avl_remove_lock(avl_tree_lock *t, avl *a) __attribute__((warn_unused_result));
+avl *avl_remove(avl_tree *t, avl *a) __attribute__((warn_unused_result));
/* Find the element into the tree that equal to a
* (equal as returned by t->compar())
else return strcmp(((NAME_VALUE *)a)->name, ((NAME_VALUE *)b)->name);
}
-#define dictionary_name_value_index_add_nolock(dict, nv) do { NETDATA_DICTIONARY_STATS_INSERTS_PLUS1(dict); avl_insert(&((dict)->values_index), (avl *)(nv)); } while(0)
-#define dictionary_name_value_index_del_nolock(dict, nv) do { NETDATA_DICTIONARY_STATS_DELETES_PLUS1(dict); avl_remove(&(dict->values_index), (avl *)(nv)); } while(0)
-
static inline NAME_VALUE *dictionary_name_value_index_find_nolock(DICTIONARY *dict, const char *name, uint32_t hash) {
NAME_VALUE tmp;
tmp.hash = (hash)?hash:simple_hash(name);
}
// index it
- dictionary_name_value_index_add_nolock(dict, nv);
+ NETDATA_DICTIONARY_STATS_INSERTS_PLUS1(dict);
+ if(unlikely(avl_insert(&((dict)->values_index), (avl *)(nv)) != (avl *)nv))
+ error("dictionary: INTERNAL ERROR: duplicate insertion to dictionary.");
+
NETDATA_DICTIONARY_STATS_ENTRIES_PLUS1(dict);
return nv;
static void dictionary_name_value_destroy_nolock(DICTIONARY *dict, NAME_VALUE *nv) {
debug(D_DICTIONARY, "Destroying name value entry for name '%s'.", nv->name);
- dictionary_name_value_index_del_nolock(dict, nv);
+ NETDATA_DICTIONARY_STATS_DELETES_PLUS1(dict);
+ if(unlikely(avl_remove(&(dict->values_index), (avl *)(nv)) != (avl *)nv))
+ error("dictionary: INTERNAL ERROR: dictionary invalid removal of node.");
NETDATA_DICTIONARY_STATS_ENTRIES_MINUS1(dict);
tc_device_compare
};
-#define tc_device_index_add(st) avl_insert(&tc_device_root_index, (avl *)(st))
-#define tc_device_index_del(st) avl_remove(&tc_device_root_index, (avl *)(st))
+#define tc_device_index_add(st) (struct tc_device *)avl_insert(&tc_device_root_index, (avl *)(st))
+#define tc_device_index_del(st) (struct tc_device *)avl_remove(&tc_device_root_index, (avl *)(st))
static inline struct tc_device *tc_device_index_find(const char *id, uint32_t hash) {
struct tc_device tmp;
else return strcmp(((struct tc_class *)a)->id, ((struct tc_class *)b)->id);
}
-#define tc_class_index_add(st, rd) avl_insert(&((st)->classes_index), (avl *)(rd))
-#define tc_class_index_del(st, rd) avl_remove(&((st)->classes_index), (avl *)(rd))
+#define tc_class_index_add(st, rd) (struct tc_class *)avl_insert(&((st)->classes_index), (avl *)(rd))
+#define tc_class_index_del(st, rd) (struct tc_class *)avl_remove(&((st)->classes_index), (avl *)(rd))
static inline struct tc_class *tc_class_index_find(struct tc_device *st, const char *id, uint32_t hash) {
struct tc_class tmp;
debug(D_TC_LOOP, "Removing from device '%s' class '%s', parentid '%s', leafid '%s', seen=%d", n->id, c->id, c->parentid?c->parentid:"", c->leafid?c->leafid:"", c->seen);
- tc_class_index_del(n, c);
+ if(unlikely(tc_class_index_del(n, c) != c))
+ error("plugin_tc: INTERNAL ERROR: attempt remove class '%s' from device '%s': removed a different calls", c->id, n->id);
freez(c->id);
freez(c->name);
d->enabled = (char)-1;
avl_init(&d->classes_index, tc_class_compare);
- tc_device_index_add(d);
+ if(unlikely(tc_device_index_add(d) != d))
+ error("plugin_tc: INTERNAL ERROR: removing device '%s' removed a different device.", d->id);
if(!tc_device_root) {
tc_device_root = d;
c->leaf_hash = simple_hash(c->leafid);
}
- tc_class_index_add(n, c);
+ if(unlikely(tc_class_index_add(n, c) != c))
+ error("plugin_tc: INTERNAL ERROR: attempt index class '%s' on device '%s': already exists", c->id, n->id);
}
c->seen = 1;
else tc_device_root = n->prev;
}
- tc_device_index_del(n);
+ if(unlikely(tc_device_index_del(n) != n))
+ error("plugin_tc: INTERNAL ERROR: removing device '%s' removed a different device.", n->id);
while(n->classes) tc_class_free(n, n->classes);
// should only happen when netdata starts
extern int registry_init(void);
-/*
// free all data held by the registry
// should only happen when netdata exits
extern void registry_free(void);
-*/
// HTTP requests handled by the registry
extern int registry_request_access_json(struct web_client *w, char *person_guid, char *machine_guid, char *url, char *name, time_t when);
// PERSON_URL
extern REGISTRY_PERSON_URL *registry_person_url_index_find(REGISTRY_PERSON *p, const char *url);
-extern REGISTRY_PERSON_URL *registry_person_url_index_add(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) __attribute__((warn_unused_result));
+extern REGISTRY_PERSON_URL *registry_person_url_index_add(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) __attribute__((returns_nonnull, warn_unused_result));
extern REGISTRY_PERSON_URL *registry_person_url_index_del(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) __attribute__((warn_unused_result));
extern REGISTRY_PERSON_URL *registry_person_url_allocate(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY_URL *u, char *name, size_t namelen, time_t when);
// REGISTRY_URL INDEX
extern int registry_url_compare(void *a, void *b);
-extern REGISTRY_URL *registry_url_index_del(REGISTRY_URL *u);
-extern REGISTRY_URL *registry_url_index_add(REGISTRY_URL *u) __attribute__((returns_nonnull));
+extern REGISTRY_URL *registry_url_index_del(REGISTRY_URL *u) __attribute__((warn_unused_result));
+extern REGISTRY_URL *registry_url_index_add(REGISTRY_URL *u) __attribute__((returns_nonnull, warn_unused_result));
// REGISTRY_URL MANAGEMENT
extern REGISTRY_URL *registry_url_get(const char *url, size_t urllen) __attribute__((returns_nonnull));
RRDFAMILY *ret = rrdfamily_index_add(&localhost, rc);
if(ret != rc)
- fatal("INTERNAL ERROR: Expected to INSERT RRDFAMILY '%s' into index, but inserted '%s'.", rc->family, (ret)?ret->family:"NONE");
+ fatal("RRDFAMILY: INTERNAL ERROR: Expected to INSERT RRDFAMILY '%s' into index, but inserted '%s'.", rc->family, (ret)?ret->family:"NONE");
}
rc->use_count++;
if(!rc->use_count) {
RRDFAMILY *ret = rrdfamily_index_del(&localhost, rc);
if(ret != rc)
- fatal("INTERNAL ERROR: Expected to DELETE RRDFAMILY '%s' from index, but deleted '%s'.", rc->family, (ret)?ret->family:"NONE");
+ fatal("RRDFAMILY: INTERNAL ERROR: Expected to DELETE RRDFAMILY '%s' from index, but deleted '%s'.", rc->family, (ret)?ret->family:"NONE");
if(rc->variables_root_index.avl_tree.root != NULL)
- fatal("INTERNAL ERROR: Variables index of RRDFAMILY '%s' that is freed, is not empty.", rc->family);
+ fatal("RRDFAMILY: INTERNAL ERROR: Variables index of RRDFAMILY '%s' that is freed, is not empty.", rc->family);
freez((void *)rc->family);
freez(rc);
else return strcmp(((RRDDIM *)a)->id, ((RRDDIM *)b)->id);
}
-#define rrddim_index_add(st, rd) avl_insert_lock(&((st)->dimensions_index), (avl *)(rd))
-#define rrddim_index_del(st,rd ) avl_remove_lock(&((st)->dimensions_index), (avl *)(rd))
+#define rrddim_index_add(st, rd) (RRDDIM *)avl_insert_lock(&((st)->dimensions_index), (avl *)(rd))
+#define rrddim_index_del(st,rd ) (RRDDIM *)avl_remove_lock(&((st)->dimensions_index), (avl *)(rd))
static RRDDIM *rrddim_index_find(RRDSET *st, const char *id, uint32_t hash) {
RRDDIM tmp;
rrddimvar_rename_all(rd);
pthread_rwlock_unlock(&st->rwlock);
- rrdset_index_add_name(&localhost, st);
+ if(unlikely(rrdset_index_add_name(&localhost, st) != st))
+ error("RRDSET: INTERNAL ERROR: attempted to index duplicate chart name '%s'", st->name);
}
// ----------------------------------------------------------------------------
rrdsetvar_create(st, "update_every", RRDVAR_TYPE_INT, &st->update_every, 0);
}
- rrdset_index_add(&localhost, st);
+ if(unlikely(rrdset_index_add(&localhost, st) != st))
+ error("RRDSET: INTERNAL ERROR: attempt to index duplicate chart '%s'", st->id);
rrdsetcalc_link_matching(st);
rrdcalctemplate_link_matching(st);
pthread_rwlock_unlock(&st->rwlock);
- rrddim_index_add(st, rd);
+ if(unlikely(rrddim_index_add(st, rd) != rd))
+ error("RRDDIM: INTERNAL ERROR: attempt to index duplicate dimension '%s' on chart '%s'", rd->id, st->id);
return(rd);
}
while(rd->variables)
rrddimvar_free(rd->variables);
- rrddim_index_del(st, rd);
+ if(unlikely(rrddim_index_del(st, rd) != rd))
+ error("RRDDIM: INTERNAL ERROR: attempt to remove from index dimension '%s' on chart '%s', removed a different dimension.", rd->id, st->id);
// free(rd->annotations);
if(rd->mapped == RRD_MEMORY_MODE_SAVE) {
while(st->dimensions)
rrddim_free(st, st->dimensions);
- rrdset_index_del(&localhost, st);
+ if(unlikely(rrdset_index_del(&localhost, st) != st))
+ error("RRDSET: INTERNAL ERROR: attempt to remove from index chart '%s', removed a different chart.", st->id);
st->rrdfamily->use_count--;
if(!st->rrdfamily->use_count)