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