1 /** 2 * @file rwlock.c Pthread read/write locking 3 * 4 * Copyright (C) 2010 Creytiv.com 5 */ 6 #define _GNU_SOURCE 1 7 #include <pthread.h> 8 #include <re_types.h> 9 #include <re_mem.h> 10 #include <re_lock.h> 11 12 13 #define DEBUG_MODULE "rwlock" 14 #define DEBUG_LEVEL 5 15 #include <re_dbg.h> 16 17 18 struct lock { 19 pthread_rwlock_t lock; 20 }; 21 22 23 static void lock_destructor(void *data) 24 { 25 struct lock *l = data; 26 27 int err = pthread_rwlock_destroy(&l->lock); 28 if (err) { 29 DEBUG_WARNING("pthread_rwlock_destroy: %m\n", err); 30 } 31 } 32 33 34 int lock_alloc(struct lock **lp) 35 { 36 struct lock *l; 37 int err; 38 39 if (!lp) 40 return EINVAL; 41 42 l = mem_zalloc(sizeof(*l), lock_destructor); 43 if (!l) 44 return ENOMEM; 45 46 err = pthread_rwlock_init(&l->lock, NULL); 47 if (err) 48 goto out; 49 50 *lp = l; 51 52 out: 53 if (err) 54 mem_deref(l); 55 return err; 56 } 57 58 59 void lock_read_get(struct lock *l) 60 { 61 int err; 62 63 if (!l) 64 return; 65 66 err = pthread_rwlock_rdlock(&l->lock); 67 if (err) { 68 DEBUG_WARNING("lock_read_get: %m\n", err); 69 } 70 } 71 72 73 void lock_write_get(struct lock *l) 74 { 75 int err; 76 77 if (!l) 78 return; 79 80 err = pthread_rwlock_wrlock(&l->lock); 81 if (err) { 82 DEBUG_WARNING("lock_write_get: %m\n", err); 83 } 84 } 85 86 87 int lock_read_try(struct lock *l) 88 { 89 if (!l) 90 return EINVAL; 91 return pthread_rwlock_tryrdlock(&l->lock); 92 } 93 94 95 int lock_write_try(struct lock *l) 96 { 97 if (!l) 98 return EINVAL; 99 return pthread_rwlock_trywrlock(&l->lock); 100 } 101 102 103 void lock_rel(struct lock *l) 104 { 105 int err; 106 107 if (!l) 108 return; 109 110 err = pthread_rwlock_unlock(&l->lock); 111 if (err) { 112 DEBUG_WARNING("lock_rel: %m\n", err); 113 } 114 } 115