////////////////////////////////////////////////////////////
//
//     	Implementation of classes
//	AMutexAttributes, AMutex
//
//      Copyright 2001 Alexander Liss
//
////////////////////////////////////////////////////////////

#include "AMutex.h"

pthread_mutex_t MutexPattern = PTHREAD_MUTEX_INITIALIZER;


	// AMutexAttributes

AMutexAttributes::AMutexAttributes()
{ 
	
	  status = ::pthread_mutexattr_init(&attributes);
}
	
AMutexAttributes::~AMutexAttributes()
{ 

	  if(!status) ::pthread_mutexattr_destroy(&attributes);
}

int AMutexAttributes::set_type(int z)
{ 
	if(status) return -1; 
	
	return ::pthread_mutexattr_settype(&attributes,z); 
}


      	
int AMutexAttributes::set_shared() // used with many processes
{ 
	if(status) return -1;
	
  	return ::pthread_mutexattr_setpshared(&attributes,PTHREAD_PROCESS_SHARED); 
}
      	
             	
int AMutexAttributes::set_protocol(int z) 
{ 
	if(status) return -1;
	
  	return ::pthread_mutexattr_setprotocol(&attributes,z); 
}
  
int AMutexAttributes::set_ceiling(int z)
{ 
	if(status) return -1;
	
  	int g=set_protocol(PTHREAD_PRIO_PROTECT);
  	
  	if(!g) g=::pthread_mutexattr_setprioceiling(&attributes,z); 
  	
  	return g; 
}
      	  


	// AMutex
	
    	// default attributes
AMutex::AMutex():status(0)
{ 
	
	  mutex = MutexPattern;
	  status = ::pthread_mutex_init(&mutex,0); 
}	  

	
AMutex::AMutex(const AMutexAttributes& z):status(0)
{ 

	mutex = MutexPattern;
	status = ::pthread_mutex_init(&mutex,&z.attributes);

}

	
AMutex::~AMutex()
{ 
	if(!status) 
		::pthread_mutex_destroy(&mutex); 
}
      
int AMutex::trylock()
{ 
	if(status) return -1;
	
      	return ::pthread_mutex_trylock(&mutex); 
}
      	
int AMutex::lock()
{ 
	if(status) return -1;
	
	return ::pthread_mutex_lock(&mutex); 
}
      
int AMutex::unlock()
{ 
	if(status) return -1;
	
	return ::pthread_mutex_unlock(&mutex); 
}