void avl_read_lock(avl_tree_lock *t) {
#ifndef AVL_WITHOUT_PTHREADS
#ifdef AVL_LOCK_WITH_MUTEX
- pthread_mutex_lock(&t->mutex);
+ if(unlikely(pthread_mutex_lock(&t->mutex) != 0))
+ error("Cannot get mutex of an AVL");
#else
- pthread_rwlock_rdlock(&t->rwlock);
+ if(unlikely(pthread_rwlock_rdlock(&t->rwlock) != 0))
+ error("Cannot get read lock of an AVL");
#endif
#endif /* AVL_WITHOUT_PTHREADS */
}
void avl_write_lock(avl_tree_lock *t) {
#ifndef AVL_WITHOUT_PTHREADS
#ifdef AVL_LOCK_WITH_MUTEX
- pthread_mutex_lock(&t->mutex);
+ if(unlikely(pthread_mutex_lock(&t->mutex) != 0)
+ error("Cannot get mutex of an AVL");
#else
- pthread_rwlock_wrlock(&t->rwlock);
+ if(unlikely(pthread_rwlock_wrlock(&t->rwlock) != 0))
+ error("Cannot write lock an AVL.");
#endif
#endif /* AVL_WITHOUT_PTHREADS */
}
void avl_unlock(avl_tree_lock *t) {
#ifndef AVL_WITHOUT_PTHREADS
#ifdef AVL_LOCK_WITH_MUTEX
- pthread_mutex_unlock(&t->mutex);
+ if(unlikely(pthread_mutex_unlock(&t->mutex) != 0))
+ error("Cannot unlock mutex of an AVL");
#else
- pthread_rwlock_unlock(&t->rwlock);
+ if(unlikely(pthread_rwlock_unlock(&t->rwlock) != 0))
+ error("Cannot unlock an AVL");
#endif
#endif /* AVL_WITHOUT_PTHREADS */
}
};
typedef struct rrdset RRDSET;
-#define rrdset_rdlock(st) pthread_rwlock_rdlock(&((st)->rrdset_rwlock))
-#define rrdset_wrlock(st) pthread_rwlock_wrlock(&((st)->rrdset_rwlock))
-#define rrdset_unlock(st) pthread_rwlock_unlock(&((st)->rrdset_rwlock))
-
// ----------------------------------------------------------------------------
// these loop macros make sure the linked list is accessed with the right lock
typedef struct rrdhost RRDHOST;
extern RRDHOST *localhost;
-#define rrdhost_rdlock(h) pthread_rwlock_rdlock(&((h)->rrdhost_rwlock))
-#define rrdhost_wrlock(h) pthread_rwlock_wrlock(&((h)->rrdhost_rwlock))
-#define rrdhost_unlock(h) pthread_rwlock_unlock(&((h)->rrdhost_rwlock))
+static inline void rrdhost_rdlock(RRDHOST *host) {
+ if(unlikely(pthread_rwlock_rdlock(&host->rrdhost_rwlock) != 0))
+ error("Cannot obtain read lock on host '%s'", host->hostname);
+}
+
+static inline void rrdhost_wrlock(RRDHOST *host) {
+ if(unlikely(pthread_rwlock_wrlock(&host->rrdhost_rwlock) != 0))
+ error("Cannot obtain write lock on host '%s'", host->hostname);
+}
+
+static inline void rrdhost_unlock(RRDHOST *host) {
+ if(unlikely(pthread_rwlock_unlock(&host->rrdhost_rwlock) != 0))
+ error("Cannot unlock host '%s'", host->hostname);
+}
+
// ----------------------------------------------------------------------------
// these loop macros make sure the linked list is accessed with the right lock
// global lock for all RRDHOSTs
extern pthread_rwlock_t rrd_rwlock;
-#define rrd_rdlock() pthread_rwlock_rdlock(&rrd_rwlock)
-#define rrd_wrlock() pthread_rwlock_wrlock(&rrd_rwlock)
-#define rrd_unlock() pthread_rwlock_unlock(&rrd_rwlock)
+
+static inline void rrd_rdlock() {
+ if(unlikely(pthread_rwlock_rdlock(&rrd_rwlock) != 0))
+ error("Cannot read lock the RRD database.");
+}
+
+static inline void rrd_wrlock() {
+ if(unlikely(pthread_rwlock_wrlock(&rrd_rwlock) != 0))
+ error("Cannot write lock the RRD database.");
+}
+
+static inline void rrd_unlock() {
+ if(unlikely(pthread_rwlock_unlock(&rrd_rwlock) != 0))
+ error("Cannot unlock the RRD database.");
+}
+
+static inline void rrdset_rdlock(RRDSET *st) {
+ if(unlikely(pthread_rwlock_rdlock(&st->rrdset_rwlock) != 0))
+ error("Cannot read lock RRDSET '%s' of host '%s'", st->id, st->rrdhost->hostname);
+}
+
+static inline void rrdset_wrlock(RRDSET *st) {
+ if(unlikely(pthread_rwlock_wrlock(&st->rrdset_rwlock) != 0))
+ error("Cannot write lock RRDSET '%s' of host '%s'", st->id, st->rrdhost->hostname);
+}
+
+static inline void rrdset_unlock(RRDSET *st) {
+ if(unlikely(pthread_rwlock_unlock(&st->rrdset_rwlock) != 0))
+ error("Cannot unlock RRDSET '%s' of host '%s'", st->id, st->rrdhost->hostname);
+}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// RRDSET - create a chart
+static inline RRDSET *rrdset_find_on_create(RRDHOST *host, const char *fullid) {
+ RRDSET *st = rrdset_find(host, fullid);
+ if(unlikely(st)) {
+ rrdset_flag_clear(st, RRDSET_FLAG_OBSOLETE);
+ debug(D_RRD_CALLS, "RRDSET '%s', already exists.", fullid);
+ return st;
+ }
+
+ return NULL;
+}
+
RRDSET *rrdset_create(
RRDHOST *host
, const char *type
char fullid[RRD_ID_LENGTH_MAX + 1];
snprintfz(fullid, RRD_ID_LENGTH_MAX, "%s.%s", type, id);
- RRDSET *st = rrdset_find(host, fullid);
+ RRDSET *st = rrdset_find_on_create(host, fullid);
+ if(st) return st;
+
+ rrdhost_wrlock(host);
+
+ st = rrdset_find_on_create(host, fullid);
if(st) {
- rrdset_flag_clear(st, RRDSET_FLAG_OBSOLETE);
- debug(D_RRD_CALLS, "RRDSET '%s', already exists.", fullid);
+ rrdhost_unlock(host);
return st;
}
avl_init_lock(&st->variables_root_index, rrdvar_compare);
pthread_rwlock_init(&st->rrdset_rwlock, NULL);
- rrdhost_wrlock(host);
if(name && *name) rrdset_set_name(st, name);
else rrdset_set_name(st, id);
RRDDIM *last;
// there is dimension to free
// upgrade our read lock to a write lock
- pthread_rwlock_unlock(&st->rrdset_rwlock);
- pthread_rwlock_wrlock(&st->rrdset_rwlock);
+ rrdset_unlock(st);
+ rrdset_wrlock(st);
for( rd = st->dimensions, last = NULL ; likely(rd) ; ) {
// remove it only it is not updated in rrd_delete_unupdated_dimensions seconds