/*
* Copyright 2008, 2011 Free Software Foundation, Inc.
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Affero General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program 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 Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/


#ifndef THREADS_H
#define THREADS_H

#include <pthread.h>
#include <iostream>
#include <assert.h>
#include <unistd.h>

class Mutex;


/**@name Multithreaded access for standard streams. */
//@{

/**@name Functions for gStreamLock. */
//@{
extern Mutex gStreamLock;	///< global lock for cout and cerr
void lockCerr();		///< call prior to writing cerr
void unlockCerr();		///< call after writing cerr
void lockCout();		///< call prior to writing cout
void unlockCout();		///< call after writing cout
//@}

/**@name Macros for standard messages. */
//@{
#define COUT(text) { lockCout(); std::cout << text; unlockCout(); }
#define CERR(text) { lockCerr(); std::cerr << __FILE__ << ":" << __LINE__ << ": " << text; unlockCerr(); }
#ifdef NDEBUG
#define DCOUT(text) {}
#define OBJDCOUT(text) {}
#else
#define DCOUT(text) { COUT(__FILE__ << ":" << __LINE__ << " " << text); }
#define OBJDCOUT(text) { DCOUT(this << " " << text); } 
#endif
//@}
//@}



/**@defgroup C++ wrappers for pthread mechanisms. */
//@{

/** A class for recursive mutexes based on pthread_mutex. */
class Mutex {

	private:

	pthread_mutex_t mMutex;
	pthread_mutexattr_t mAttribs;

	public:

	Mutex();

	~Mutex();

	void lock() { pthread_mutex_lock(&mMutex); }

	bool trylock() { return pthread_mutex_trylock(&mMutex)==0; }

	void unlock() { pthread_mutex_unlock(&mMutex); }

	friend class Signal;

};


class ScopedLock {

	private:
	Mutex& mMutex;

	public:
	ScopedLock(Mutex& wMutex) :mMutex(wMutex) { mMutex.lock(); }
	~ScopedLock() { mMutex.unlock(); }

};




/** A C++ interthread signal based on pthread condition variables. */
class Signal {

	private:

	mutable pthread_cond_t mSignal;

	public:

	Signal() { int s = pthread_cond_init(&mSignal,NULL); assert(!s); }

	~Signal() { pthread_cond_destroy(&mSignal); }

	/**
		Block for the signal up to the cancellation timeout.
		Under Linux, spurious returns are possible.
	*/
	void wait(Mutex& wMutex, unsigned timeout) const;

	/**
		Block for the signal.
		Under Linux, spurious returns are possible.
	*/
	void wait(Mutex& wMutex) const
		{ pthread_cond_wait(&mSignal,&wMutex.mMutex); }

	void signal() { pthread_cond_signal(&mSignal); }

	void broadcast() { pthread_cond_broadcast(&mSignal); }

};



#define START_THREAD(thread,function,argument) \
	thread.start((void *(*)(void*))function, (void*)argument);

/** A C++ wrapper for pthread threads.  */
class Thread {

	private:

	pthread_t mThread;
	pthread_attr_t mAttrib;
	// FIXME -- Can this be reduced now?
	size_t mStackSize;
	

	public:

	/** Create a thread in a non-running state. */
	Thread(size_t wStackSize = (65536*4)):mThread((pthread_t)0) {
		pthread_attr_init(&mAttrib);	// (pat) moved this here.
		mStackSize=wStackSize;
	}

	/**
		Destroy the Thread.
		It should be stopped and joined.
	*/
	// (pat) If the Thread is destroyed without being started, then mAttrib is undefined.  Oops.
	~Thread() { pthread_attr_destroy(&mAttrib); }


	/** Start the thread on a task. */
	void start(void *(*task)(void*), void *arg);

	/** Join a thread that will stop on its own. */
	void join() {
		if (mThread) {
			int s = pthread_join(mThread, NULL);
			assert(!s);
		}
	}

	/** Send cancelation to thread */
	void cancel() { pthread_cancel(mThread); }
};




#endif
// vim: ts=4 sw=4
