re/src/lock/lock.c
2011-03-01 11:11:08 +00:00

142 lines
2.2 KiB
C

/**
* @file lock/lock.c Pthread mutex locking
*
* Copyright (C) 2010 Creytiv.com
*/
#include <string.h>
#define __USE_UNIX98 1
#include <pthread.h>
#include <re_types.h>
#include <re_mem.h>
#include <re_lock.h>
#define DEBUG_MODULE "lock"
#define DEBUG_LEVEL 5
#include <re_dbg.h>
#ifndef RELEASE
#define LOCK_DEBUG 0
#endif
/** Defines a lock */
struct lock {
pthread_mutex_t m;
};
static void lock_destructor(void *data)
{
struct lock *l = data;
int err = pthread_mutex_destroy(&l->m);
if (err) {
DEBUG_WARNING("pthread_mutex_destroy: %s\n", strerror(err));
}
}
/**
* Allocate a new lock
*
* @param lp Pointer to allocated lock object
*
* @return 0 if success, otherwise errorcode
*/
int lock_alloc(struct lock **lp)
{
pthread_mutexattr_t attr;
struct lock *l;
if (!lp)
return EINVAL;
l = mem_zalloc(sizeof(*l), lock_destructor);
if (!l)
return ENOMEM;
(void)pthread_mutex_init(&l->m, NULL);
pthread_mutexattr_init(&attr);
#if LOCK_DEBUG
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
DEBUG_NOTICE("init debug lock\n");
#else
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
#endif
pthread_mutex_init(&l->m, &attr);
*lp = l;
return 0;
}
/**
* Get the lock for reading
*
* @param l Lock object
*/
void lock_read_get(struct lock *l)
{
const int err = pthread_mutex_lock(&l->m);
if (err) {
DEBUG_WARNING("lock_read_get: %s\n", strerror(err));
}
}
/**
* Get the lock for writing
*
* @param l Lock object
*/
void lock_write_get(struct lock *l)
{
const int err = pthread_mutex_lock(&l->m);
if (err) {
DEBUG_WARNING("lock_write_get: %s\n", strerror(err));
}
}
/**
* Attempt to get a lock for reading
*
* @param l Lock object
*
* @return 0 if success, otherwise errorcode
*/
int lock_read_try(struct lock *l)
{
return pthread_mutex_trylock(&l->m);
}
/**
* Attempt to get a lock for writing
*
* @param l Lock object
*
* @return 0 if success, otherwise errorcode
*/
int lock_write_try(struct lock *l)
{
return pthread_mutex_trylock(&l->m);
}
/**
* Release a lock
*
* @param l Lock object
*/
void lock_rel(struct lock *l)
{
const int err = pthread_mutex_unlock(&l->m);
if (err) {
DEBUG_WARNING("lock_rel: %s\n", strerror(err));
}
}