/***************************************************************************

    supportware
    Copyright (C) 2001-2008 by c.holzheuer
    c.holzheuer@sourceworx.org

    This program 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; either version 2 of the License, or
    (at your option) any later version.

***************************************************************************/

#ifndef DDTHREADMUTEX_H
#define DDTHREADMUTEX_H

#include <pthread.h>
#include <stdexcept>
#include <ddbaseobject.h>

class ddthreadautomutex;


/// ddthreadmutex
/**
	Sollte nicht solo sondern aus sicherheitsgründen nur als automutex
	verwendet werden.
*/

	
class ddthreadmutex
{

friend class ddthreadautomutex;

public:

  /**
		Creates a ddthreadmutex object.
	*/

  inline explicit ddthreadmutex()
  {
  	int rc = pthread_mutex_init( &_mutex, 0 );
  	if( rc != 0 )
  		throw runtime_error( "ddthreadmutex: Error creating ddthreadmutex:" + ddstrutil::from_int(rc) );
  }


	/**
		Destroys the ddthreadmutex object.
	*/

	inline ~ddthreadmutex() noexcept
  {
  	int rc = pthread_mutex_destroy( &_mutex );
  	if( rc != 0 )
        ;
			//throw runtime_error( "ddthreadmutex: Error destroying ddthreadmutex: " + ddstrutil::from_int(rc) );
        //log_( "ddthreadmutex: Error destroying ddthreadmutex: " + ddstrutil::from_int(rc) );
  }
  
	/**
		Acquires the ddthreadmutex lock. Calling thread is
		blocked until the ddthreadmutex lock is granted.
	 	Recursive calls are not supported.
	*/

  inline void lock()
  {
		int rc = pthread_mutex_lock( &_mutex );
  	if( rc != 0 )
		  throw runtime_error( "ddthreadmutex.: Error locking ddthreadmutex:" + ddstrutil::from_int(rc) );
  }

  
	/**
	 Unlocks the ddthreadmutex object. Caller must hold the
	 lock before calling unlock.
	*/

  inline void unlock()
  {
  	int rc = pthread_mutex_unlock( &_mutex );
  	if (rc != 0)
		  throw runtime_error( "ddthreadmutex: Error unlocking ddthreadmutex:" + ddstrutil::from_int(rc) );
  }
   

	inline pthread_mutex_t* get_real_mutex()
  {
  	return &_mutex;
  }

private:

	ddthreadmutex( const ddthreadmutex& );
	ddthreadmutex& operator=( const ddthreadmutex& );

	pthread_mutex_t _mutex;

};


/***************************************************************************

    supportware
    Copyright (C) 2001-2008 by c.holzheuer
    c.holzheuer@sourceworx.org

    This program 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; either version 2 of the License, or
    (at your option) any later version.

***************************************************************************/


/// ddthreadautomutex
/**
	an autmatic mutex
*/


class ddthreadautomutex
{

public:

  
	inline explicit ddthreadautomutex( ddthreadmutex& mutex )
	:  _mutex( &mutex )
	{		
		_mutex->lock();
	}


	inline ~ddthreadautomutex()
	{
		_mutex->unlock();
	}

	
private:

	ddthreadautomutex( const ddthreadautomutex& );
	ddthreadautomutex& operator=( const ddthreadautomutex& );

	ddthreadmutex* _mutex;

};

#endif
