Toshihiro Shimizu 890ddd
#include <stdexcept> /* std::domain_error */</stdexcept>
Toshihiro Shimizu 890ddd
#include "igs_resource_thread.h"
Toshihiro Shimizu 890ddd
#include "igs_resource_msg_from_err.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const HANDLE igs::resource::thread_run(
Toshihiro Shimizu 890ddd
	unsigned(__stdcall *function)(void *), void *func_arg, const int priority)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//unsigned thread_addr=0;
Toshihiro Shimizu 890ddd
	HANDLE thread_id = reinterpret_cast<handle>(::_beginthreadex(</handle>
Toshihiro Shimizu 890ddd
		NULL, 0, function, func_arg, 0, NULL));
Toshihiro Shimizu 890ddd
	if (0 == thread_id) {
Toshihiro Shimizu 890ddd
		throw std::domain_error(igs_resource_msg_from_err(
Toshihiro Shimizu 890ddd
			TEXT("_beginthreadex(-)"), errno));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
	vc2005 MSDN より
Toshihiro Shimizu 890ddd
	BOOL SetThreadPriority(int nPriority);
Toshihiro Shimizu 890ddd
	に与える値を優先度の高いものから順に並べます。
Toshihiro Shimizu 890ddd
	THREAD_PRIORITY_TIME_CRITICAL		プロセスにより15 or 31
Toshihiro Shimizu 890ddd
	THREAD_PRIORITY_HIGHEST			標準より2ポイント高い
Toshihiro Shimizu 890ddd
	THREAD_PRIORITY_ABOVE_NORMAL		標準より1ポイント高い
Toshihiro Shimizu 890ddd
	THREAD_PRIORITY_NORMAL		-1	標準
Toshihiro Shimizu 890ddd
	THREAD_PRIORITY_BELOW_NORMAL		標準より1ポイント低い
Toshihiro Shimizu 890ddd
	THREAD_PRIORITY_LOWEST			標準より2ポイント低い
Toshihiro Shimizu 890ddd
	THREAD_PRIORITY_IDLE			プロセスにより1 or 16
Toshihiro Shimizu 890ddd
	*/
Toshihiro Shimizu 890ddd
	if (0 == ::SetThreadPriority(thread_id, priority)) {
Toshihiro Shimizu 890ddd
		throw std::domain_error(igs_resource_msg_from_err(
Toshihiro Shimizu 890ddd
			TEXT("SetThreadPriority(-)"), ::GetLastError()));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return thread_id;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
以下の関数でthreadの終了を見るよりも、
Toshihiro Shimizu 890ddd
thread内で終了時に終了スイッチを入れる方法で感知する。
Toshihiro Shimizu 890ddd
linuxでのやり方にあわせる。2011-03-30
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
const bool igs::resource::thread_was_done(const HANDLE thread_id)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	DWORD exit_code = 0;
Toshihiro Shimizu 890ddd
	if (0 == ::GetExitCodeThread(thread_id, &exit_code)) {
Toshihiro Shimizu 890ddd
		throw std::domain_error(igs_resource_msg_from_err(
Toshihiro Shimizu 890ddd
			"GetExitCodeThread(-)", ::GetLastError()));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (exit_code == STILL_ACTIVE) {
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
void igs::resource::thread_join(const HANDLE thread_id)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	thread_wait(thread_id);
Toshihiro Shimizu 890ddd
	thread_close(thread_id);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
void igs::resource::thread_wait(const HANDLE thread_id)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/* _endthreadex(-)はスレッドハンドルを閉じない??? */
Toshihiro Shimizu 890ddd
	if (WAIT_FAILED == ::WaitForSingleObject(thread_id, INFINITE)) {
Toshihiro Shimizu 890ddd
		throw std::domain_error(igs_resource_msg_from_err(
Toshihiro Shimizu 890ddd
			TEXT("WaitForSingleObject(-)"), ::GetLastError()));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
void igs::resource::thread_close(const HANDLE thread_id)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (0 == ::CloseHandle(thread_id)) {
Toshihiro Shimizu 890ddd
		throw std::domain_error(igs_resource_msg_from_err(
Toshihiro Shimizu 890ddd
			TEXT("CloseHandle(-)"), ::GetLastError()));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}