#include <Locker.h>
#include <sys/time.h>

PthreadMutex::PthreadMutex()
{
    m_pMutex = new pthread_mutex_t;
    pthread_mutex_init(m_pMutex, NULL);
}

PthreadMutex::~PthreadMutex()
{
    pthread_mutex_destroy(m_pMutex);
    delete m_pMutex;
}

int PthreadMutex::Lock()
{
    return pthread_mutex_lock(m_pMutex);
}

int PthreadMutex::TryLock()
{
    return pthread_mutex_trylock(m_pMutex);
}

int PthreadMutex::Unlock()
{
    return pthread_mutex_unlock(m_pMutex);
}

PthreadCond::PthreadCond()
{
    m_pCond = new pthread_cond_t;
    pthread_cond_init(m_pCond, NULL);
}

PthreadCond::~PthreadCond()
{
    pthread_cond_destroy(m_pCond);
    delete m_pCond;
}

int PthreadCond::Wait(PthreadMutex& m, float waitTime)
{
    if (waitTime > 0.0)
    {
    	struct timespec timeout;
	struct timeval now;
	gettimeofday(&now, 0);


	timeout.tv_sec = now.tv_sec + (int)waitTime;
	waitTime -= (int)waitTime;
	timeout.tv_nsec = (now.tv_usec + (int)(waitTime * 1000000)) * 1000;

	if (timeout.tv_nsec >= 1000000000)
	{
	    timeout.tv_nsec -= 1000000000;
            timeout.tv_sec++;
	}
	// time limited conditional waiting here!
	// sometimes decoder thread could be stoped
	// and we would have wait here forever
	return pthread_cond_timedwait(m_pCond, m.m_pMutex, &timeout);
    }

    return pthread_cond_wait(m_pCond, m.m_pMutex);
}

int PthreadCond::Broadcast()
{
    return pthread_cond_broadcast(m_pCond);
}

Locker::Locker(PthreadMutex& mutex) : m_pMutex(mutex.m_pMutex)
{
    pthread_mutex_lock(m_pMutex);
}

Locker::Locker(pthread_mutex_t* mutex) : m_pMutex(mutex)
{
    pthread_mutex_lock(m_pMutex);
}

Locker::~Locker()
{
    pthread_mutex_unlock(m_pMutex);
}
