[sheepdog] [PATCH] introduce wrapper functions for pthread_rwlock
Liu Yuan
namei.unix at gmail.com
Wed Aug 7 20:07:31 CEST 2013
On Wed, Aug 07, 2013 at 11:46:32PM +0900, MORITA Kazutaka wrote:
> Currently, we don't check the return values of pthread_rwlock_rdlock()
> and pthread_rwlock_wrlock(). When they returns an error, we can call
> pthread_rwlock_unlock() even if another thread has the lock. This can
> lead to a bug which is difficult to find.
>
> Those functions can actually return error. For example, when
> pthread_rwlock_rdlock() is called when a write lock is already owned,
> it returns EDEADLK without locking. It is difficult to make sure that
> we don't have this kind of deadlock, so checking the return values
> strictly is important to ensure our codes is correct.
>
> Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
> ---
> collie/farm/farm.c | 6 ++---
> include/util.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++
> lib/sockfd_cache.c | 36 +++++++++++++++---------------
> sheep/cluster/zookeeper.c | 32 +++++++++++++--------------
> sheep/md.c | 42 +++++++++++++++++------------------
> sheep/object_cache.c | 44 ++++++++++++++++++-------------------
> sheep/object_list_cache.c | 26 +++++++++++-----------
> sheep/vdi.c | 22 +++++++++----------
> sheepfs/volume.c | 30 ++++++++++++-------------
> 9 files changed, 175 insertions(+), 119 deletions(-)
>
> diff --git a/collie/farm/farm.c b/collie/farm/farm.c
> index 2a4e307..3da9f8d 100644
> --- a/collie/farm/farm.c
> +++ b/collie/farm/farm.c
> @@ -21,7 +21,7 @@
> static char farm_object_dir[PATH_MAX];
> static char farm_dir[PATH_MAX];
>
> -static pthread_rwlock_t vdi_list_lock = PTHREAD_RWLOCK_INITIALIZER;
> +static sd_mutex_t vdi_list_lock = SD_MUTEX_INITIALIZER;
> struct vdi_entry {
> char name[SD_MAX_VDI_LEN];
> uint64_t vdi_size;
> @@ -350,9 +350,9 @@ static void do_load_object(struct work *work)
> sw->entry.nr_copies) < 0)
> goto error;
>
> - pthread_rwlock_wrlock(&vdi_list_lock);
> + sd_mutex_wrlock(&vdi_list_lock);
> insert_vdi(buffer);
> - pthread_rwlock_unlock(&vdi_list_lock);
> + sd_mutex_unlock(&vdi_list_lock);
> }
>
> farm_show_progress(uatomic_add_return(&loaded, 1), trunk_get_count());
> diff --git a/include/util.h b/include/util.h
> index 0d50f4f..bfbe451 100644
> --- a/include/util.h
> +++ b/include/util.h
> @@ -11,6 +11,8 @@
> #include <search.h>
> #include <urcu/uatomic.h>
> #include <sys/eventfd.h>
> +#include <pthread.h>
> +#include <errno.h>
>
> #include "logger.h"
> #include "bitops.h"
> @@ -257,6 +259,60 @@ static inline int refcount_dec(refcnt_t *rc)
> return uatomic_sub_return(&rc->val, 1);
> }
>
> +/* wrapper for pthread_rwlock */
> +
> +#define SD_MUTEX_INITIALIZER PTHREAD_RWLOCK_INITIALIZER
> +
> +typedef pthread_rwlock_t sd_mutex_t;
> +
> +static inline void sd_mutex_init(sd_mutex_t *mutex)
> +{
> + int ret;
> +
> + do {
> + ret = pthread_rwlock_init(mutex, NULL);
> + } while (ret == EAGAIN);
> +
> + if (ret != 0)
> + panic("failed to initialize a mutex, %s", strerror(ret));
> +}
> +
> +static inline void sd_mutex_destroy(sd_mutex_t *mutex)
> +{
> + int ret = pthread_rwlock_destroy(mutex);
> +
> + if (ret != 0)
> + panic("failed to destroy a mutex, %s", strerror(ret));
> +}
> +
> +static inline void sd_mutex_rdlock(sd_mutex_t *mutex)
> +{
> + int ret;
> +
> + do {
> + ret = pthread_rwlock_rdlock(mutex);
> + } while (ret == EAGAIN);
> +
> + if (ret != 0)
> + panic("failed to lock for reading, %s", strerror(ret));
> +}
> +
> +static inline void sd_mutex_wrlock(sd_mutex_t *mutex)
> +{
> + int ret = pthread_rwlock_wrlock(mutex);
> +
> + if (ret != 0)
> + panic("failed to lock for writing, %s", strerror(ret));
> +}
> +
> +static inline void sd_mutex_unlock(sd_mutex_t *mutex)
> +{
> + int ret = pthread_rwlock_unlock(mutex);
> +
> + if (ret != 0)
> + panic("failed to unlock, %s", strerror(ret));
> +}
sd_mutex_t -> sd_lock
sd_mutex_init -> sd_init_lock
sd_mutex_unlock -> sd_unlock
sd_mutex_rdlock -> sd_read_lock
sd_mutex_wrlock -> sd_write_lock
sd_mutex_destroy -> sd_destroy_lock
Thanks
Yuan
More information about the sheepdog
mailing list