/* ------------------------------------------------------------------
 * Copyright (C) 2008 PacketVideo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 * -------------------------------------------------------------------
 */
// -*- c++ -*-
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

//                  OSCL_MUTEX (M U T E X  I M P L E M E N T A T I O N)

// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =


/*! \file oscl_mutex.cpp .This file provides MUTEX implementation that can be ported
to three OS LINUX, SYMBIAN & WIN32
*/

#include "oscl_mutex.h"


#include "oscl_assert.h"

OSCL_EXPORT_REF OsclMutex::OsclMutex()
{
    bCreated = false;
}

OSCL_EXPORT_REF OsclMutex::~OsclMutex()
{
    //make sure it's closed
    if (bCreated)
        Close();
}

/*
 * Creates the Mutex
 *
 * @param MutexName    NULL terminated string.
 *
 * @return Returns the Error whether it is success or failure
 *incase of failure it will return what is the specific error
 */
OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclMutex::Create()
{
    if (bCreated)
        return OsclProcStatus::INVALID_OPERATION_ERROR;


    int result = pthread_mutex_init(&ObjMutex, NULL);
    if (result == 0)
    {
        bCreated = true;
        return OsclProcStatus::SUCCESS_ERROR;
    }
    else
        return ErrorMapping(result);


}


/**
 * Locks the Mutex
 *
 * @param It wont take any parameters
 *
 * @return Returns the Error whether it is success or failure
 *incase of failure it will return what is the specific error
 */
OSCL_EXPORT_REF void OsclMutex::Lock()
{
    //verify the mutex is created.
    OSCL_ASSERT(bCreated);


    pthread_mutex_lock(&ObjMutex);

}


/**
 * Try to lock the mutex,if the Mutex is already locked calling thread
 * immediately returns with out blocking
 * @param It wont take any parameters
 *
 * @return Returns the Error whether it is success or failure
 *incase of failure it will return what is the specific error
 */
OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclMutex::TryLock()
{
    if (!bCreated)
        return OsclProcStatus::INVALID_OPERATION_ERROR;


    int result = pthread_mutex_trylock(&ObjMutex);
    switch (result)
    {
        case 0:
            return OsclProcStatus::SUCCESS_ERROR;
        case EBUSY:
            return OsclProcStatus::MUTEX_LOCKED_ERROR;
        default:
            return ErrorMapping(result);
    }

}

/**
 * Releases the Mutex
 *
 * @param It wont take any parameters
 *
 * @return Returns the Error whether it is success or failure
 *incase of failure it will return what is the specific error
 */
OSCL_EXPORT_REF void OsclMutex::Unlock()
{
    //verify the mutex is created.
    OSCL_ASSERT(bCreated);


    pthread_mutex_unlock(&ObjMutex);

}



/**
 * Closes the Mutex
 *
 * @param It wont take any prameters
 *
 * @return Returns the Error whether it is success or failure
 *incase of failure it will return what is the specific error
 */
OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclMutex::Close()
{
    if (!bCreated)
        return OsclProcStatus::INVALID_OPERATION_ERROR;


    int result = pthread_mutex_destroy(&ObjMutex);
    if (result == 0)
    {
        bCreated = false;
        return OsclProcStatus::SUCCESS_ERROR;
    }
    else
        return ErrorMapping(result);

}



/**
 * Error Mapping
 *
 * @param It will take error returned by OS specific API
 *
 * @return Returns specific error
 */
OsclProcStatus::eOsclProcError OsclMutex::ErrorMapping(int32 Error)
{


    switch (Error)
    {
        case 0:
            return OsclProcStatus::SUCCESS_ERROR;
        case EAGAIN :
            return  OsclProcStatus::SYSTEM_RESOURCES_UNAVAILABLE_ERROR;
        case EINVAL :
            return  OsclProcStatus::INVALID_ARGUMENT_ERROR;
        case ENOMEM :
            return  OsclProcStatus::NOT_ENOUGH_MEMORY_ERROR;
        case EFAULT  :
            return  OsclProcStatus::INVALID_POINTER_ERROR;
        case EBUSY:
            return 	OsclProcStatus::MUTEX_LOCKED_ERROR;
        default:
            return OsclProcStatus::OTHER_ERROR;
    }

}

OSCL_EXPORT_REF OsclThreadLock::OsclThreadLock()
{
    iMutex.Create();
}
OSCL_EXPORT_REF OsclThreadLock::~OsclThreadLock()
{
    iMutex.Close();
}
OSCL_EXPORT_REF void OsclThreadLock::Lock()
{
    iMutex.Lock();
}
OSCL_EXPORT_REF void OsclThreadLock::Unlock()
{
    iMutex.Unlock();
}

