#ifndef H_CORAL_LIB_MULTITHREAD
#define H_CORAL_LIB_MULTITHREAD
// This file is part of the Coral project.
// Please read the copyright notice in the LICENSE file.

#include <bits/gthr.h>
#include <coral/coral.h>
#include <coral/lib/noncopy.h>
#include <coral/lib/debugstream.h>

#include <iostream>

namespace coral {

class EXPORT_coral LockMutex : public noncopy {
 private:
     __gthread_mutex_t& m;
 public:
     LockMutex(__gthread_mutex_t& p) throw () : m(p)  {
#ifndef NDEBUG
	     if (__gthread_mutex_trylock(&m)) {
		     dlog << DEBUGLEVEL_DEBUG << "Couldn't lock the mutex at " << &m << std::endl
			       << "If you are non-multithreading on uniprocessor this will deadlock." << std::endl;
		     __gthread_mutex_lock(&m);
	     } 
#else
	     __gthread_mutex_lock(&m);
#endif
     }
     ~LockMutex() throw () {
	  __gthread_mutex_unlock(&m);
     }
};

#ifndef __GTHREAD_MUTEX_INIT
# define EXTERN_MUTEX(mutex) extern __gthread_mutex_t mutex
# define INIT_MUTEX(mutex) __gthread_mutex_t mutex
# define INIT_MUTEX_FUNC(mutex) __GTHREAD_MUTEX_INIT_FUNCTION(mutex)
#else
# define EXTERN_MUTEX(mutex) extern __gthread_mutex_t mutex
# define INIT_MUTEX(mutex) __gthread_mutex_t mutex = __GTHREAD_MUTEX_INIT
# define INIT_MUTEX_FUNC(mutex) do { } while(0)
#endif

# ifdef PLATFORM_WINDOWS
#  include <sys/time.h>
#  ifdef COMPILING_coral
EXTERN_MUTEX(mutex_localtime_r);
#  endif
EXPORT_coral struct tm* localtime_r(time_t* curtime, struct tm* user_tm);
# else
#  define HAVE_LOCALTIME_R 1
inline EXPORT_coral struct tm*
	localtime_r(time_t* curtime, struct tm* user_tm) {
	return ::localtime_r(curtime, user_tm);
}
# endif

}

#endif

