
#include "hbapi.h"          // Agent API include file
#include "mutex.h"

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// EventMutex implementation
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

// Constructor
EventMutex::EventMutex()
{
#ifdef _WIN32

    _eventMutex = CreateEvent( NULL, FALSE, FALSE, NULL );

#else

    pthread_cond_init( &_eventMutex, 0 );

#endif
}

// Signal condition/event 
void EventMutex::SignalEvent()
{
#ifdef _WIN32

   if ( ! PulseEvent ( _eventMutex ) )

#else
    if ( pthread_cond_signal( &_eventMutex ) )
#endif
    {
        hbAPI::writeLog("Cannot signal event.\n");
    }

}

// Wait for condition/event
void EventMutex::WaitForEvent( Mutex & mutex )
{
#ifdef _WIN32
    if ( WAIT_FAILED == WaitForSingleObject( _eventMutex, INFINITE ) )
#else
    if ( pthread_cond_wait( &_eventMutex, &mutex._criticalSection ) )
#endif
    {
        hbAPI::writeLog("Wait for condition failed.\n");
    }

}


//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// Mutex implementation
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

// Constructor
Mutex::Mutex()
{
#ifdef _WIN32

    InitializeCriticalSection( &_criticalSection );

#else

    pthread_mutexattr_t attr;
    pthread_mutex_init( &_criticalSection, &attr );

#endif
}

// Lock mutex for the calling thread
void Mutex::Lock()
{
#ifdef _WIN32

    EnterCriticalSection( &_criticalSection );

#else

    if ( pthread_mutex_lock( &_criticalSection ) )
    {
        hbAPI::writeLog("Cannot lock mutex.\n");
    }

#endif
}

// Release mutex for the calling thread
void Mutex::Release()
{
#ifdef _WIN32

    LeaveCriticalSection( &_criticalSection );

#else

    if ( pthread_mutex_unlock( &_criticalSection ) )
    {
        hbAPI::writeLog("Cannot unlock mutex.\n");
    }

#endif
}

