

/* Thread_condition 是多线程的条件控制类，主要是控制线程的启停和退出
 * 线程创建后，一般是循环运行，
 * 为了防止线程暂满整个cpu，那么需要线程在不工作的是否进入等待状态。
 * Thread_condition 就可以控制线程的运行状态。
 *
	std::atomic<bool> m_pass_ever		//线程能否直接通过等待，对后面的线程也生效。
	std::atomic<bool> m_pass_once		//线程能否直接通过等待，一次（通过一次之后，wait里面自动改为false）
 * 外部调用notify系列的函数，唤醒等待的线程，让线程执行功能函数。
 * 如果需要线程循环多次执行功能函数，那么就使用 notify_all(true)，后面的线程可以直接通过等待了。
 * 再使用 notify_all(false) ，即可停止线程，让其继续等待。
 * 如果只想要线程执行一次，那就使用 notify_all(false, true)
 * 注：notify_all(false, true)和notify_one(false, true) 一样，只能让其中一个线程执行一次
 *
 * m_kill_flag //是否杀死线程，让线程强制退出，
 * 外部调用 kill_all() 函数，可以直接通知线程自动退出。
	//杀死所有的线程，强制退出线程函数，只是操作受当前Thread_condition影响的所有线程
	//唤醒所有线程，使其通过等待，但是不能运行功能函数，必须直接return
	// 注：只是修改m_kill为true，需要线程函数实时检测kill的状态，来return线程。
	//		通过等待之后，也要检查kill的状态，如果为真，那么就不能执行功能函数，应该直接return

 注：notify唤醒线程之后，wait里面的判断函数会重新判断。
 */

#include "thread_condition.h"

Thread_condition::Thread_condition()
{
	m_kill_flag = false;
	m_pass_ever = false;
	m_pass_once = false;
	m_working_flag = false;
}
Thread_condition::~Thread_condition()
{
	kill_all();
}

//无限等待，由 is_pass_wait 决定是否阻塞。
//返回m_pass，
bool Thread_condition::wait()
{
	std::unique_lock<std::mutex> loc(m_mutex);
	m_condition_variable.wait(loc,std::bind(is_pass_wait,this));
	bool t_pass = is_pass_wait(this);
	m_pass_once = false;

	//只要前面通过了, 那就进入工作状态
	m_working_flag = true;

	return t_pass;
}
//等待一定的时间（默认时间单位：毫秒ms），由 is_pass_wait 决定是否阻塞。
//return：is_pass_wait的结果，	true：线程直接通过等待，false：线程超时了，然后通过等待。
//注意了：线程阻塞期间，是不会return的。
bool Thread_condition::wait_for_millisecond(unsigned int millisecond)
{
	std::unique_lock<std::mutex> loc(m_mutex);
	m_condition_variable.wait_for(loc, std::chrono::milliseconds(millisecond), std::bind(is_pass_wait, this));
	bool t_pass = is_pass_wait(this);
	m_pass_once = false;

	//只要前面通过了, 那就进入工作状态 , 超时通过也算通过
	m_working_flag = true;

	return t_pass;
}


//唤醒已经阻塞的线程，唤醒一个线程
//pass_ever 或者 pass_once 为真时，才能唤醒线程。都为假时，线程进入等待。
void Thread_condition::notify_one(bool pass_ever, bool pass_once)
{
	std::unique_lock<std::mutex> loc(m_mutex);
	m_pass_ever = pass_ever;
	m_pass_once = pass_once;
	m_condition_variable.notify_one();
}
//唤醒已经阻塞的线程，唤醒全部线程
//pass_ever 或者 pass_once 为真时，才能唤醒线程。都为假时，线程进入等待。
void Thread_condition::notify_all(bool pass_ever, bool pass_once)
{
	std::unique_lock<std::mutex> loc(m_mutex);
	m_pass_ever = pass_ever;
	m_pass_once = pass_once;
	m_condition_variable.notify_all();
}
//注：notify_all(false, true)和notify_one(false, true) 一样，只能让其中一个线程执行一次


//杀死所有的线程，强制退出线程函数，只是操作受当前Thread_condition影响的所有线程
//唤醒所有线程，使其通过等待，但是不能运行功能函数，必须直接return
// 注：只是修改m_kill为true，需要线程函数实时检测kill的状态，来return线程。
//		通过等待之后，也要检查kill的状态，如果为真，那么就不能执行功能函数，应该直接return
void Thread_condition::kill_all()
{
	std::unique_lock<std::mutex> loc(m_mutex);
	m_kill_flag = true;
	m_condition_variable.notify_all();
}

//判断是否存活，只有活着才能继续支持子线程从功能函数，否则需要强制退出函数并结束子线程
bool Thread_condition::is_alive()
{
	return !m_kill_flag;
}


//判断是否等待, 外部线程通过这个函数来查询this线程的工作状态,
bool Thread_condition::is_waiting()
{
	return !m_working_flag;
}
//判断是否工作, 外部线程通过这个函数来查询this线程的工作状态,
bool Thread_condition::is_working()
{
	return m_working_flag;
}


bool Thread_condition::get_kill_flag()
{
	return m_kill_flag;
}
bool Thread_condition::get_pass_ever()
{
	return m_pass_ever;
}
bool Thread_condition::get_pass_once()
{
	return m_pass_once;
}
void Thread_condition::set_kill_flag(bool kill)
{
	m_kill_flag = kill;
}
void Thread_condition::set_pass_ever(bool pass_ever)
{
	m_pass_ever = pass_ever;
}
void Thread_condition::set_pass_once(bool pass_once)
{
	m_pass_once = pass_once;
}
void Thread_condition::reset(bool kill, bool pass_ever, bool pass_once)
{
	m_kill_flag = kill;
	m_pass_ever = pass_ever;
	m_pass_once = pass_once;
}


//判断线程是否可以通过等待，wait系列函数的判断标志
//注：m_kill或者m_pass为真时，return true
bool Thread_condition::is_pass_wait(Thread_condition * other)
{
	if ( other == NULL )
	{
		throw (other);
		return false;
	}

	bool result = (other->m_kill_flag || other->m_pass_ever || other->m_pass_once);

	//如果不能通过等待, 那么线程状态改为等待中,
	if ( !result )
	{
		other->m_working_flag = false;
	}


	return result;
}

