/**
 * @file
 * $Id$
 * $Revision$
 * $Author$
 * $Date$
 *
 * This file is part of The iWear Framework.
 *
 * The iWear Framework is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by the
 * Free Software Foundation as in version 2 of the License.

 * 
 * The iWear Framework is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __IWEAR_THREADLOCKED_H
#define __IWEAR_THREADLOCKED_H

#ifndef __IWEAR_IWMUTEX_H
#include <iwear/iwmutex.h>
#endif

namespace iwear
{

/**
 * Since a lot of classes will probably want functionality like this, there is
 * a big chance that this class will suffer from multiple inheritance path
 * ambiguities. Therefore, every class that derives from this one should always
 * derive virtually from here. This is important !!!
 * @note This is always a fast mutex !!!!
 */
class IWAPIT threadlocked
{
private:
protected:
public:
    virtual ~threadlocked() { }

    mutable Mutex mutex;

    int Lock( void );
   /**
    * Whenever an implementation can choose the sequence of execution when
    * accessing possibly locked resources, it should check with this function
    * if the mutex is locked, and if not, deferr access to the resources. While
    * this does not give a speedup on uniprocessor systems (everything is
    * executed sequentially anyways) it might give a speedup on multiprocessor
    * system, since otherwise one process would waste CPU cycles waiting for
    * the lock instead of doing other things. It might even make sense to
    * choose this behaviour when interacting with locked resources over the
    * network.
    * @note It could be dangerous whenver a locked resource is interrupted,
    * e.g. when calling this through a network.  
    * @warning Be carefull to always unlock whenever u need it, mutexes have
    * many pitfalls. I recommend to read some docs about it prior to proceed
    * using them.
    */
    int TryLock( void );

    int Unlock( void );
};

/// Convenience typedef for legacy iwear code
typedef threadlocked ThreadLocked;

inline int threadlocked::Lock( void )
{
    return mutex.Lock();
}

inline int threadlocked::Unlock( void )
{
    return mutex.Unlock();
}

inline int threadlocked::TryLock( void )
{
    return mutex.TryLock();
}

}

#endif
