/***************************************************************************
                Work Pool
                -----------------------------------------
	begin      : 2011/10/27
	copyright  : (C) 2011 SolutionBox Inc.
	author     : Service 1 Team
	email      : svc1@solbox.com
	version    : 3.0.1

    CopyRight(C) 2011 SolutionBox Inc. All Rights reserved.
    Redistribution and use in source and binary forms, with or with out
    modification, are not permitted in outside of SolutionBox Inc.
***************************************************************************/
#ifndef __WORK_POOL_H__
#define __WORK_POOL_H__

#include <string>
#include <map>

using namespace std;

# if __GNUC__ >= 3
#   include <ext/hash_map>
using namespace __gnu_cxx;
# else
#   include <hash_map>
# endif

typedef int (*work_notifyfn)(void *object, short success);

struct hash_key 
{
	size_t operator() (const string &k) const
	{
		return __stl_hash_string(k.c_str());
	}
};
struct compare_key
{
	bool operator () (const string s1, const string &s2) const
	{
		return s1 == s2;
	}
};

typedef hash_map<string, short, hash_key, compare_key> workurimap;

#include "SyncList.h"

class CWork
{
public:
	CWork();
	~CWork();

	bool	init();
	bool	run(CSyncInfo info, string rundata, work_notifyfn nofi = NULL, void * parm = NULL);

	void	setexit(bool v);
	void	setenablesync(const char* szOn) {m_enablesync = szOn;}
	
	pthread_t* getworkhandle() {return &m_thread;}

	const char*		getrundata() { return m_rundata.c_str(); }
	int				getsetp()	{ return m_step; }	
private:
	static void* working(void * pdata);

private:
	int					m_step;
	bool				m_exit;
	string				m_rundata;
	
	CSyncInfo			m_syncinfo;

	string				m_workuri;
	work_notifyfn		m_nofi;
	void*				m_parm;
	string				m_enablesync;

	pthread_t			m_thread;
	pthread_cond_t		m_workcond;
	pthread_mutex_t		m_workmutex;
};

class CWorkPool
{
public:
	enum WORK_SATAUSE
	{
		WORKING		= 0,
		NOTWORK		= 1
	};

public:
	static	void			init();
	static	CWorkPool*		getInstance();
	static	void			release();

	int	CreatePool( int poolcnt = 10 );
	int DestroyPool();

	bool	addworkuri(string tranid, string uri, string &workuri, 
					bool sourcedata = false, int timeout = 5);
	bool	delworkuri(string key);

	void	printstatus(string prefixed = "");
	void	printstatusex(string prefixed = "");

	CWork*	GetWorkPool(int timeout = 0);
	void	ReleaseWork(CWork *w);

private:
	CWorkPool();
	~CWorkPool();

private:
	static CWorkPool* m_inst;

	pthread_mutex_t			m_mutex;
	pthread_mutex_t			m_mutexuri;
	pthread_mutex_t			m_mutextry;
	
	workurimap				m_workurimap;
	map<CWork*, short> m_pool;
};

#endif // __WORK_POOL_H__
