@cryptotaxi247 / netdata-1 / commits / 2065f1910

locks error handling

Costa Tsaousis (ktsaou) committed Mar 12, 2017 at 05:29 UTC 2065f19101bdfd8d83ec0335edf9b04a2b4c7d1f
3 files changed +77 -22
src/avl.c
+12 -6
@@ -315,9 +315,11 @@ int avl_traverse(avl_tree *t, int (*callback)(void *entry, void *data), void *da
315 void avl_read_lock(avl_tree_lock *t) {
316 #ifndef AVL_WITHOUT_PTHREADS
317 #ifdef AVL_LOCK_WITH_MUTEX
318 - pthread_mutex_lock(&t->mutex);
318 + if(unlikely(pthread_mutex_lock(&t->mutex) != 0))
319 + error("Cannot get mutex of an AVL");
320 #else
320 - pthread_rwlock_rdlock(&t->rwlock);
321 + if(unlikely(pthread_rwlock_rdlock(&t->rwlock) != 0))
322 + error("Cannot get read lock of an AVL");
323 #endif
324 #endif /* AVL_WITHOUT_PTHREADS */
325 }
@@ -325,9 +327,11 @@ void avl_read_lock(avl_tree_lock *t) {
327 void avl_write_lock(avl_tree_lock *t) {
328 #ifndef AVL_WITHOUT_PTHREADS
329 #ifdef AVL_LOCK_WITH_MUTEX
328 - pthread_mutex_lock(&t->mutex);
330 + if(unlikely(pthread_mutex_lock(&t->mutex) != 0)
331 + error("Cannot get mutex of an AVL");
332 #else
330 - pthread_rwlock_wrlock(&t->rwlock);
333 + if(unlikely(pthread_rwlock_wrlock(&t->rwlock) != 0))
334 + error("Cannot write lock an AVL.");
335 #endif
336 #endif /* AVL_WITHOUT_PTHREADS */
337 }
@@ -335,9 +339,11 @@ void avl_write_lock(avl_tree_lock *t) {
339 void avl_unlock(avl_tree_lock *t) {
340 #ifndef AVL_WITHOUT_PTHREADS
341 #ifdef AVL_LOCK_WITH_MUTEX
338 - pthread_mutex_unlock(&t->mutex);
342 + if(unlikely(pthread_mutex_unlock(&t->mutex) != 0))
343 + error("Cannot unlock mutex of an AVL");
344 #else
340 - pthread_rwlock_unlock(&t->rwlock);
345 + if(unlikely(pthread_rwlock_unlock(&t->rwlock) != 0))
346 + error("Cannot unlock an AVL");
347 #endif
348 #endif /* AVL_WITHOUT_PTHREADS */
349 }
src/rrd.h
+45 -10
@@ -325,10 +325,6 @@ struct rrdset {
325 };
326 typedef struct rrdset RRDSET;
327
328 -#define rrdset_rdlock(st) pthread_rwlock_rdlock(&((st)->rrdset_rwlock))
329 -#define rrdset_wrlock(st) pthread_rwlock_wrlock(&((st)->rrdset_rwlock))
330 -#define rrdset_unlock(st) pthread_rwlock_unlock(&((st)->rrdset_rwlock))
331 -
328 // ----------------------------------------------------------------------------
329 // these loop macros make sure the linked list is accessed with the right lock
330
@@ -452,9 +448,21 @@ struct rrdhost {
448 typedef struct rrdhost RRDHOST;
449 extern RRDHOST *localhost;
450
455 -#define rrdhost_rdlock(h) pthread_rwlock_rdlock(&((h)->rrdhost_rwlock))
456 -#define rrdhost_wrlock(h) pthread_rwlock_wrlock(&((h)->rrdhost_rwlock))
457 -#define rrdhost_unlock(h) pthread_rwlock_unlock(&((h)->rrdhost_rwlock))
451 +static inline void rrdhost_rdlock(RRDHOST *host) {
452 + if(unlikely(pthread_rwlock_rdlock(&host->rrdhost_rwlock) != 0))
453 + error("Cannot obtain read lock on host '%s'", host->hostname);
454 +}
455 +
456 +static inline void rrdhost_wrlock(RRDHOST *host) {
457 + if(unlikely(pthread_rwlock_wrlock(&host->rrdhost_rwlock) != 0))
458 + error("Cannot obtain write lock on host '%s'", host->hostname);
459 +}
460 +
461 +static inline void rrdhost_unlock(RRDHOST *host) {
462 + if(unlikely(pthread_rwlock_unlock(&host->rrdhost_rwlock) != 0))
463 + error("Cannot unlock host '%s'", host->hostname);
464 +}
465 +
466
467 // ----------------------------------------------------------------------------
468 // these loop macros make sure the linked list is accessed with the right lock
@@ -470,9 +478,36 @@ extern RRDHOST *localhost;
478 // global lock for all RRDHOSTs
479
480 extern pthread_rwlock_t rrd_rwlock;
473 -#define rrd_rdlock() pthread_rwlock_rdlock(&rrd_rwlock)
474 -#define rrd_wrlock() pthread_rwlock_wrlock(&rrd_rwlock)
475 -#define rrd_unlock() pthread_rwlock_unlock(&rrd_rwlock)
481 +
482 +static inline void rrd_rdlock() {
483 + if(unlikely(pthread_rwlock_rdlock(&rrd_rwlock) != 0))
484 + error("Cannot read lock the RRD database.");
485 +}
486 +
487 +static inline void rrd_wrlock() {
488 + if(unlikely(pthread_rwlock_wrlock(&rrd_rwlock) != 0))
489 + error("Cannot write lock the RRD database.");
490 +}
491 +
492 +static inline void rrd_unlock() {
493 + if(unlikely(pthread_rwlock_unlock(&rrd_rwlock) != 0))
494 + error("Cannot unlock the RRD database.");
495 +}
496 +
497 +static inline void rrdset_rdlock(RRDSET *st) {
498 + if(unlikely(pthread_rwlock_rdlock(&st->rrdset_rwlock) != 0))
499 + error("Cannot read lock RRDSET '%s' of host '%s'", st->id, st->rrdhost->hostname);
500 +}
501 +
502 +static inline void rrdset_wrlock(RRDSET *st) {
503 + if(unlikely(pthread_rwlock_wrlock(&st->rrdset_rwlock) != 0))
504 + error("Cannot write lock RRDSET '%s' of host '%s'", st->id, st->rrdhost->hostname);
505 +}
506 +
507 +static inline void rrdset_unlock(RRDSET *st) {
508 + if(unlikely(pthread_rwlock_unlock(&st->rrdset_rwlock) != 0))
509 + error("Cannot unlock RRDSET '%s' of host '%s'", st->id, st->rrdhost->hostname);
510 +}
511
512 // ----------------------------------------------------------------------------
513
src/rrdset.c
+20 -6
@@ -328,6 +328,17 @@ void rrdset_delete(RRDSET *st) {
328 // ----------------------------------------------------------------------------
329 // RRDSET - create a chart
330
331 +static inline RRDSET *rrdset_find_on_create(RRDHOST *host, const char *fullid) {
332 + RRDSET *st = rrdset_find(host, fullid);
333 + if(unlikely(st)) {
334 + rrdset_flag_clear(st, RRDSET_FLAG_OBSOLETE);
335 + debug(D_RRD_CALLS, "RRDSET '%s', already exists.", fullid);
336 + return st;
337 + }
338 +
339 + return NULL;
340 +}
341 +
342 RRDSET *rrdset_create(
343 RRDHOST *host
344 , const char *type
@@ -357,10 +368,14 @@ RRDSET *rrdset_create(
368 char fullid[RRD_ID_LENGTH_MAX + 1];
369 snprintfz(fullid, RRD_ID_LENGTH_MAX, "%s.%s", type, id);
370
360 - RRDSET *st = rrdset_find(host, fullid);
371 + RRDSET *st = rrdset_find_on_create(host, fullid);
372 + if(st) return st;
373 +
374 + rrdhost_wrlock(host);
375 +
376 + st = rrdset_find_on_create(host, fullid);
377 if(st) {
362 - rrdset_flag_clear(st, RRDSET_FLAG_OBSOLETE);
363 - debug(D_RRD_CALLS, "RRDSET '%s', already exists.", fullid);
378 + rrdhost_unlock(host);
379 return st;
380 }
381
@@ -523,7 +538,6 @@ RRDSET *rrdset_create(
538 avl_init_lock(&st->variables_root_index, rrdvar_compare);
539
540 pthread_rwlock_init(&st->rrdset_rwlock, NULL);
526 - rrdhost_wrlock(host);
541
542 if(name && *name) rrdset_set_name(st, name);
543 else rrdset_set_name(st, id);
@@ -1250,8 +1264,8 @@ void rrdset_done(RRDSET *st) {
1264 RRDDIM *last;
1265 // there is dimension to free
1266 // upgrade our read lock to a write lock
1253 - pthread_rwlock_unlock(&st->rrdset_rwlock);
1254 - pthread_rwlock_wrlock(&st->rrdset_rwlock);
1267 + rrdset_unlock(st);
1268 + rrdset_wrlock(st);
1269
1270 for( rd = st->dimensions, last = NULL ; likely(rd) ; ) {
1271 // remove it only it is not updated in rrd_delete_unupdated_dimensions seconds