///////////////////////////////////////////////////////////////////////////////
/// @file deThreadPool.hpp
///
/// @brief 
///
/// @author trajar
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date Jun 2002
/// @author trajar
/// @remarks Creation
///
///////////////////////////////////////////////////////////////////////////////

#ifndef	_DETHREADPOOL_HPP
#define	_DETHREADPOOL_HPP

#ifndef		_DENET_HPP
 #include	"deNet.hpp"
#endif

#ifndef		_DETHREAD_HPP
 #include	"deThread.hpp"
#endif

#ifndef		_DESYNCHOBJECT_HPP
 #include	"deSynchObject.hpp"
#endif

#include	<VECTOR>
#include	<STACK>
#include	<QUEUE>

class DENET_API deThreadPool
{
public:

	deThreadPool(void);
	virtual ~deThreadPool(void);

	bool		CreateThreads( int iNum );
	deThread *	ActivateIdleThread( deThread::ActiveProcess process, void * param, DWORD paramSize, DWORD dwDesc = NULL, bool bCreateThread = false );
	int			ActivateQueuedJobs( int iNumCreatedThreads = 0 );
	bool		DestroyAllThreads( bool bForceKill = false );

	DWORD	GetNumActiveThreads(void);
	DWORD	GetNumIdleThreads(void);

	// function called by deThread when going to STATUS_SLEEP
	bool	NotifyOnIdle( deThread * pThread );

	static  deThreadPool * GetMgr(void)		{ return m_Singleton; }

protected:

	class JobDesc
	{
	public:

		JobDesc(void)	: m_pProcessData(NULL)		{ }
		~JobDesc(void)								{ SAFE_DELETE_ARRAY(m_pProcessData); }

		enum Flags
		{
			JOB_KILL_THREAD_ON_COMPLETION	= 0x0001,
		};

		deThread *					m_pThread;
		deThread::ActiveProcess		m_pProcess;
		BYTE	 *					m_pProcessData;
		DWORD						m_dwDesc;
	};

	typedef		std::stack<deThread*>	stackThreads;
	typedef		std::vector<JobDesc*>	aJobs;
	typedef		std::queue<JobDesc*>	queueJobs;

	queueJobs		m_queWaitingJobs;
	stackThreads	m_stkIdleThreads;
	aJobs			m_aActiveJobs;
	deSynchObject	m_SynchObject;

	static deThreadPool * m_Singleton;
};

#endif