// TKS_Mutex.cpp 
/// 
/// (c) 2002-2009 by Bastian Spiegel <bs@tkscript.de> 
///     - distributed under terms of the GNU general public license (GPL). 
/// 
///     13-Apr-2004: thanks to Carsten Busse <car.busse@gmx.de> for help with the 
///                  pthread support 

#include "tks.h" 
 

#include "TKS_Mutex.h" 
  
 
#ifdef DX_PTHREADS
#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
static pthread_mutex_t tks_pthread_mutex_t_init = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
#else
// recursive initializer not available, just use the normal one and hope it works ;)
static pthread_mutex_t tks_pthread_mutex_t_init = PTHREAD_MUTEX_INITIALIZER;
#endif // PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
TKS_Mutex::TKS_Mutex(void) { 
	////handle= PTHREAD_MUTEX_INITIALIZER; ////new pthread_mutex_t; 
/*#ifdef YAC_LINUX
   //{0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, __LOCK_INITIALIZER}
//   memset((void*)handle, 0, sizeof(pthread_mutex_t));
//   pthread_mutex_t.__m_kind = PTHREAD_MUTEX_RECURSIVE_NP;
   memcpy((void*)&handle, (const void*)&tks_pthread_mutex_t_init, sizeof(pthread_mutex_t));


#else
   handle = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; 
#endif
*/
   memcpy((void*)&handle, (const void*)&tks_pthread_mutex_t_init, sizeof(pthread_mutex_t));

	//if(handle) 
		////pthread_mutex_init(&handle,NULL /* default=single lock*/); 
} 
 
TKS_Mutex::~TKS_Mutex() { 
	/*if(handle) 
	{ 
		pthread_mutex_destroy(handle); 
		delete handle; 
		handle=NULL; 
	} */
} 
 
void TKS_Mutex::lock(void) { 
	//if(handle) 
		pthread_mutex_lock(&handle); 
} 
 
void TKS_Mutex::unlock(void) { 
	//if(handle) 
		pthread_mutex_unlock(&handle); 
} 
#else //#ifdef DX_PTHREADS
#ifdef YAC_WIN32 
TKS_Mutex::TKS_Mutex(void) { 
   ::InitializeCriticalSection( &handle ); 
} 
 
TKS_Mutex::~TKS_Mutex() { 
	::DeleteCriticalSection( &handle ); 
} 
 
void TKS_Mutex::lock(void) { 
	::EnterCriticalSection( &handle ); 
} 
 
void TKS_Mutex::unlock(void) { 
	::LeaveCriticalSection( &handle ); 
} 

#else 
// ---- NO THREADS AVAILABLE ---- 
TKS_Mutex::TKS_Mutex(void) { 
	// stub 
} 
 
TKS_Mutex::~TKS_Mutex() { 
	// stub 
} 
 
void TKS_Mutex::lock(void) { 
	// stub 
} 
 
void TKS_Mutex::unlock(void) { 
	// stub 
} 
#endif // YAC_WIN32
#endif // DX_PTHREADS

void TKS_Mutex::forceUnlock(void) { 
   // ugly hack to release a mutex when a thread holding it has crashed
   for(int i=0; i<100; i++)
   {
      unlock();
   }
} 
