
#define LOCAL_DEBUG
#include "debug.h"

#include <config.h>
#include "lockable.h"
#include <inttypes.h>
#include <errno.h>
#include <pthread.h>
#include <sys/time.h>

//#include <iostream>
//using namespace MYSTD;

lockable::lockable() { pthread_mutex_init(&__mutex, NULL); /*MYSTD::cout << "inited lock:" <<&__mutex<<endl;*/}
lockable::~lockable() { pthread_mutex_destroy(&__mutex); }
void lockable::lock() { /*cout << "locking: " << &__mutex<<endl;*/ pthread_mutex_lock(&__mutex); }
void lockable::unlock() { /*cout << "releasing: " << &__mutex<<endl;*/ pthread_mutex_unlock(&__mutex); }
bool lockable::tryLock() { return EBUSY!=pthread_mutex_trylock(&__mutex); }

condition::condition() : lockable() { pthread_cond_init(&__cond, NULL); }
condition::~condition() { pthread_cond_destroy(&__cond); }
void condition::wait() { 
    //ldbg("waiting on " << (uint64_t) &__cond); 
    pthread_cond_wait(&__cond, &__mutex); 
}
bool condition::wait(unsigned int sec, long msec)
{
    struct timeval now;
    struct timespec timeout;
    gettimeofday(&now, NULL);
    timeout.tv_sec = now.tv_sec + sec;
    timeout.tv_nsec = now.tv_usec * 1000 + msec;
    if(timeout.tv_nsec>=1000000)
    {
    	timeout.tv_sec++;
    	timeout.tv_nsec %= 1000;
    }
    return ETIMEDOUT != pthread_cond_timedwait(&__cond, &__mutex, &timeout);
}

void condition::notifyAll() { 
    //ldbg("broadcast " << (uint64_t) &__cond);
    pthread_cond_broadcast(&__cond); 
}

void condition::notify() { 
    //ldbg("signal " << (uint64_t) &__cond);
    pthread_cond_signal(&__cond); 
}



//void condition::notifyWithLocking() { lock(); notify(); unlock();}
