/* $Id$ */
/* 
 * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */

/* 
 * Note: 
 * 
 * DO NOT BUILD THIS FILE DIRECTLY. THIS FILE WILL BE INCLUDED BY os_core_*.c
 * WHEN MACRO PJ_EMULATE_RWMUTEX IS SET.
 */

/*
 * os_rwmutex.c:
 *
 * Implementation of Read-Write mutex for platforms that lack it (e.g.
 * Win32, RTEMS).
 */


struct pj_rwmutex_t
{
    pj_mutex_t *read_lock;
    /* write_lock must use semaphore, because write_lock may be released
     * by thread other than the thread that acquire the write_lock in the
     * first place.
     */
    pj_sem_t   *write_lock;
    pj_int32_t  reader_count;
};

/*
 * Create reader/writer mutex.
 *
 */
PJ_DEF(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,
				      pj_rwmutex_t **p_mutex)
{
    pj_status_t status;
    pj_rwmutex_t *rwmutex;

    PJ_ASSERT_RETURN(pool && p_mutex, PJ_EINVAL);

    *p_mutex = NULL;
    rwmutex = pj_pool_alloc(pool, sizeof(struct pj_rwmutex_t));

    status = pj_mutex_create_simple(pool, name, &rwmutex ->read_lock);
    if (status != PJ_SUCCESS)
	return status;

    status = pj_sem_create(pool, name, 1, 1, &rwmutex->write_lock);
    if (status != PJ_SUCCESS) {
	pj_mutex_destroy(rwmutex->read_lock);
	return status;
    }

    rwmutex->reader_count = 0;
    *p_mutex = rwmutex;
    return PJ_SUCCESS;
}

/*
 * Lock the mutex for reading.
 *
 */
PJ_DEF(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex)
{
    pj_status_t status;

    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);

    status = pj_mutex_lock(mutex->read_lock);
    if (status != PJ_SUCCESS) {
	pj_assert(!"This pretty much is unexpected");
	return status;
    }

    mutex->reader_count++;

    pj_assert(mutex->reader_count < 0x7FFFFFF0L);

    if (mutex->reader_count == 1)
	pj_sem_wait(mutex->write_lock);

    status = pj_mutex_unlock(mutex->read_lock);
    return status;
}

/*
 * Lock the mutex for writing.
 *
 */
PJ_DEF(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex)
{
    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
    return pj_sem_wait(mutex->write_lock);
}

/*
 * Release read lock.
 *
 */
PJ_DEF(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex)
{
    pj_status_t status;

    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);

    status = pj_mutex_lock(mutex->read_lock);
    if (status != PJ_SUCCESS) {
	pj_assert(!"This pretty much is unexpected");
	return status;
    }

    pj_assert(mutex->reader_count >= 1);

    --mutex->reader_count;
    if (mutex->reader_count == 0)
	pj_sem_post(mutex->write_lock);

    status = pj_mutex_unlock(mutex->read_lock);
    return status;
}

/*
 * Release write lock.
 *
 */
PJ_DEF(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex)
{
    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
    pj_assert(mutex->reader_count <= 1);
    return pj_sem_post(mutex->write_lock);
}


/*
 * Destroy reader/writer mutex.
 *
 */
PJ_DEF(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex)
{
    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
    pj_mutex_destroy(mutex->read_lock);
    pj_sem_destroy(mutex->write_lock);
    return PJ_SUCCESS;
}

