/* $Id$
 */
#include <pj/lock.h>
#include <pj/os.h>
#include <pj/assert.h>
#include <pj/pool.h>
#include <pj/string.h>
#include <pj/errno.h>


typedef void LOCK_OBJ;

/*
 * Lock structure.
 */
struct pj_lock_t
{
    LOCK_OBJ *lock_object;

    pj_status_t	(*acquire)	(LOCK_OBJ*);
    pj_status_t	(*tryacquire)	(LOCK_OBJ*);
    pj_status_t	(*release)	(LOCK_OBJ*);
    pj_status_t	(*destroy)	(LOCK_OBJ*);
};

typedef pj_status_t (*FPTR)(LOCK_OBJ*);

/******************************************************************************
 * Implementation of lock object with mutex.
 */
static pj_lock_t mutex_lock_template = 
{
    NULL,
    (FPTR) &pj_mutex_lock,
    (FPTR) &pj_mutex_trylock,
    (FPTR) &pj_mutex_unlock,
    (FPTR) &pj_mutex_destroy
};

static pj_status_t create_mutex_lock( pj_pool_t *pool,
				      const char *name,
				      int type,
				      pj_lock_t **lock )
{
    pj_lock_t *p_lock;
    pj_status_t rc;

    PJ_ASSERT_RETURN(pool && lock, PJ_EINVAL);

    p_lock = pj_pool_alloc(pool, sizeof(pj_lock_t));
    if (!p_lock)
	return PJ_ENOMEM;

    pj_memcpy(p_lock, &mutex_lock_template, sizeof(pj_lock_t));
    rc = pj_mutex_create(pool, name, type, (pj_mutex_t**)&p_lock->lock_object);
    if (rc != PJ_SUCCESS)
	return rc;

    *lock = p_lock;
    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pj_lock_create_simple_mutex( pj_pool_t *pool,
						 const char *name,
						 pj_lock_t **lock )
{
    return create_mutex_lock(pool, name, PJ_MUTEX_SIMPLE, lock);
}

PJ_DEF(pj_status_t) pj_lock_create_recursive_mutex( pj_pool_t *pool,
						    const char *name,
						    pj_lock_t **lock )
{
    return create_mutex_lock(pool, name, PJ_MUTEX_RECURSE, lock);
}


/******************************************************************************
 * Implementation of NULL lock object.
 */
static pj_status_t null_op(void *arg)
{
    PJ_UNUSED_ARG(arg);
    return PJ_SUCCESS;
}

static pj_lock_t null_lock_template = 
{
    NULL,
    &null_op,
    &null_op,
    &null_op,
    &null_op
};

PJ_DEF(pj_status_t) pj_lock_create_null_mutex( pj_pool_t *pool,
					       const char *name,
					       pj_lock_t **lock )
{
    PJ_UNUSED_ARG(name);
    PJ_UNUSED_ARG(pool);

    PJ_ASSERT_RETURN(lock, PJ_EINVAL);

    *lock = &null_lock_template;
    return PJ_SUCCESS;
}


/******************************************************************************
 * Implementation of semaphore lock object.
 */
#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0

static pj_lock_t sem_lock_template = 
{
    NULL,
    (FPTR) &pj_sem_wait,
    (FPTR) &pj_sem_trywait,
    (FPTR) &pj_sem_post,
    (FPTR) &pj_sem_destroy
};

PJ_DEF(pj_status_t) pj_lock_create_semaphore(  pj_pool_t *pool,
					       const char *name,
					       unsigned initial,
					       unsigned max,
					       pj_lock_t **lock )
{
    pj_lock_t *p_lock;
    pj_status_t rc;

    PJ_ASSERT_RETURN(pool && lock, PJ_EINVAL);

    p_lock = pj_pool_alloc(pool, sizeof(pj_lock_t));
    if (!p_lock)
	return PJ_ENOMEM;

    pj_memcpy(p_lock, &sem_lock_template, sizeof(pj_lock_t));
    rc = pj_sem_create( pool, name, initial, max, 
		        (pj_sem_t**)&p_lock->lock_object);
    if (rc != PJ_SUCCESS)
        return rc;

    *lock = p_lock;

    return PJ_SUCCESS;
}


#endif	/* PJ_HAS_SEMAPHORE */


PJ_DEF(pj_status_t) pj_lock_acquire( pj_lock_t *lock )
{
    PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
    return (*lock->acquire)(lock->lock_object);
}

PJ_DEF(pj_status_t) pj_lock_tryacquire( pj_lock_t *lock )
{
    PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
    return (*lock->tryacquire)(lock->lock_object);
}

PJ_DEF(pj_status_t) pj_lock_release( pj_lock_t *lock )
{
    PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
    return (*lock->release)(lock->lock_object);
}

PJ_DEF(pj_status_t) pj_lock_destroy( pj_lock_t *lock )
{
    PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
    return (*lock->destroy)(lock->lock_object);
}

