/** \file
 *
 *  Contains the Mutex, ThreadCondition, and MutexLocker class declarations.
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 */

#ifndef MUTEX_H_
#define MUTEX_H_

#include <pthread.h>
#include "utils/Timestamp.h"

/**
 *  A simple pthread Mutex abstraction
 *
 *  \ingroup utils
 */
class Mutex
{

public:

    friend class ThreadCondition;

    /// Constructor initializes the mutex
    Mutex();

    /// Lock the mutex.
    int lock();

    /// Unlock the mutex
    int unlock();

    /// Returns true if able to lock the mutex, false if already locked.
    bool tryLock();


private:
    /// The Mutex itself
    pthread_mutex_t mutex_;
    static pthread_mutexattr_t MutexAttr_;
    static bool MutexAttrInitialized_;

};

/**
 *  A simple pthread thread condition wrapper
 *
 *  \ingroup utils
 */
class ThreadCondition
{
public:
    ThreadCondition( Mutex& mutex );

    int wait();

    int timedWait( const Timespan& waitFor );

    int signal();

    int broadcast();

private:
    pthread_cond_t condition_;
    Mutex& mutex_;
};

/**
 *  An implementation of RAII for the Mutex
 *
 *  \ingroup utils
 */
class MutexLocker
{
public:
    /// Constructor "creates" a lock on the mutex
    MutexLocker( Mutex& mutex );

    /// Destructor "destroys" the lock on the mutex
    ~MutexLocker();

private:

    /// Reference to keep track of the Mutex
    Mutex& mutex_;
};



#endif /*MUTEX_H_*/
