]> arthur.barton.de Git - netdata.git/commitdiff
locks error handling
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sun, 12 Mar 2017 03:29:58 +0000 (05:29 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sun, 12 Mar 2017 03:29:58 +0000 (05:29 +0200)
src/avl.c
src/rrd.h
src/rrdset.c

index 1ec1b8ad221bc31bf4adc8636512a97db9ccbb6f..f6a997884efc5eb06c688881bd6dffddcf962ce9 100644 (file)
--- a/src/avl.c
+++ b/src/avl.c
@@ -315,9 +315,11 @@ int avl_traverse(avl_tree *t, int (*callback)(void *entry, void *data), void *da
 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 */
 }
@@ -325,9 +327,11 @@ void avl_read_lock(avl_tree_lock *t) {
 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 */
 }
@@ -335,9 +339,11 @@ void avl_write_lock(avl_tree_lock *t) {
 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 */
 }
index 2b872ed7dccacb6b312fd4cbbe17622303f44834..bc642d80bbe77c596e255fd7919070aa5704c6cc 100644 (file)
--- a/src/rrd.h
+++ b/src/rrd.h
@@ -325,10 +325,6 @@ struct rrdset {
 };
 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
 
@@ -452,9 +448,21 @@ struct rrdhost {
 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
@@ -470,9 +478,36 @@ extern RRDHOST *localhost;
 // 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);
+}
 
 // ----------------------------------------------------------------------------
 
index 1918b5cb2ee8e3e45df900f2c8eb51aa98682a58..30fd561a1349a47a29ed5a913aa8a3799d38898c 100644 (file)
@@ -328,6 +328,17 @@ void rrdset_delete(RRDSET *st) {
 // ----------------------------------------------------------------------------
 // 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
@@ -357,10 +368,14 @@ RRDSET *rrdset_create(
     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;
     }
 
@@ -523,7 +538,6 @@ RRDSET *rrdset_create(
     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);
@@ -1250,8 +1264,8 @@ void rrdset_done(RRDSET *st) {
             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