[PR]

水無瀬の部屋 > Programming > sample > tools > workthrd > workthrd.cpp
最終更新日: 2007/10/24

   1: //*********************************************************
   2: // プロジェクト: attrchng - Attributes Changer
   3: //   ファイル名: workthrd.cpp
   4: //*********************************************************
   5: #define USE_GETWORKERTHREADCANCELEVENTHANDLE // [unsafe]
   6: #include <workthrd/workthrd.h>
   7: #include <header/tooldbg.h>  // VALID_TEST(), ASSERT(), 
   8: #include <header/toolbase.h> // 
   9: #include <header/toolsys.h>
  10: 
  11: 
  12: //---------------------------------------------------------
  13: // 定数型マクロ の 定義
  14: //---------------------------------------------------------
  15: #define DBG_ALLOCNAME  "CreateWorkerThread"
  16: 
  17: 
  18: //---------------------------------------------------------
  19: // 構造体 の 宣言
  20: //---------------------------------------------------------
  21: typedef struct thread_tag 
  22: {
  23: 	size_t              magic;
  24: 	HANDLE              handle;       // スレッドへのハンドル
  25: 	HANDLE              heventCancel; // 中断用イベント
  26: 	WorkerThreadProc_t  proc;         //
  27: 	void               *param;        //
  28: } thread_t;
  29: 
  30: 
  31: //---------------------------------------------------------
  32: // ファイルスコープ関数 の 宣言
  33: //---------------------------------------------------------
  34: static bool FinishWorkerThread( thread_t *thread );
  35: static DWORD WINAPI WorkerThreadProc( void *param );
  36: 
  37: 
  38: //*********************************************************
  39: // CreateWorkerThread
  40: // サスペンド状態のスレッドを返すので、
  41: // 作業を開始するには ResumeWorkerThread() を使う。
  42: //*********************************************************
  43: thread_t *
  44: CreateWorkerThread
  45: 	(
  46: 		WorkerThreadProc_t  proc,
  47: 		void               *param
  48: 	)
  49: {
  50: 	// パラメタの仮定
  51: 	ASSERT( IsValidCodePtr( proc ) );
  52: 
  53: 	// 
  54: 	thread_t *thread = (thread_t *)malloc( sizeof( *thread ) );
  55: 	if ( ! thread )
  56: 	{
  57: 		return null;
  58: 	}
  59: 
  60: 	//
  61: 	thread->heventCancel = CreateEvent( null, true, false, null );
  62: 	if ( ! thread->heventCancel )
  63: 	{
  64: 		free( thread );
  65: 		return null;
  66: 	}
  67: 
  68: 	//
  69: 	thread->magic = sizeof( *thread );  //
  70: 	thread->proc  = proc;  //
  71: 	thread->param = param; //
  72: 
  73: 	// スレッドの作成
  74: 	DWORD dwID;
  75: 	thread->handle = BeginThreadEx
  76: 		(
  77: 			null,
  78: 			0,
  79: 			WorkerThreadProc,
  80: 			thread,
  81: 			CREATE_SUSPENDED,
  82: 			&dwID
  83: 		);
  84: 	if ( ! thread->handle )
  85: 	{
  86: 		VERIFY( CloseHandle( thread->heventCancel ) );
  87: 		free( thread );
  88: 		return null;
  89: 	}
  90: 	ASSERT( IsValidWorkerThread( thread ) );
  91: 
  92: 	//
  93: 	DBG_LOCK_ALLOCED_MEMORY( thread, DBG_ALLOCNAME ); // [DBG]
  94: 	return thread;
  95: }//CreateWorkerThread
  96: 
  97: //*********************************************************
  98: // DestroyWorkerThread
  99: //*********************************************************
 100: bool
 101: DestroyWorkerThread
 102: 	(
 103: 		thread_t *thread
 104: 	)
 105: {
 106: 	// パラメタの仮定
 107: 	ASSERT( IsValidWorkerThread( thread ) );
 108: 
 109: 	// 終了を要求して終了するまで待つ
 110: 	FinishWorkerThread( thread );
 111: 	ResumeWorkerThread( thread );
 112: 	ASSERT( IsValidWorkerThread( thread ) );
 113: 
 114: 	// 削除する
 115: 	VERIFY( CloseHandle( thread->heventCancel ) );
 116: 	thread->heventCancel = null;
 117: 
 118: 	// 削除する
 119: 	VERIFY( CloseHandle( thread->handle ) );
 120: 	thread->handle  = null;
 121: 
 122: 	//	
 123: 	DBG_UNLOCK_ALLOCED_MEMORY( thread, DBG_ALLOCNAME ); // [DBG]
 124: 	free( thread );
 125: 
 126: 	return true;
 127: }//DestroyWorkerThread
 128: 
 129: //*********************************************************
 130: // IsValidWorkerThread
 131: //*********************************************************
 132: bool
 133: IsValidWorkerThread
 134: 	(
 135: 		const thread_t *thread
 136: 	)
 137: {
 138: 	VALID_TEST( IsValidReadPtr( thread, sizeof( *thread ) ) );
 139: 	VALID_TEST( sizeof( *thread ) == thread->magic );
 140: 	VALID_TEST( thread->handle );
 141: 	VALID_TEST( thread->heventCancel );
 142: 	VALID_TEST( IsValidCodePtr( thread->proc ) );
 143: 
 144: 	return true;
 145: }//IsValidWorkerThread
 146: 
 147: //*********************************************************
 148: // GetWorkerThreadCancelEventHandle
 149: //*********************************************************
 150: HANDLE
 151: GetWorkerThreadCancelEventHandle
 152: 	(
 153: 		const thread_t *thread
 154: 	)
 155: {
 156: 	// パラメタの仮定
 157: 	ASSERT( IsValidWorkerThread( thread ) );
 158: 
 159: 	return thread->heventCancel;
 160: }//GetWorkerThreadCancelEventHandle
 161: 
 162: //*********************************************************
 163: // ResumeWorkerThread
 164: //*********************************************************
 165: bool
 166: ResumeWorkerThread
 167: 	(
 168: 		thread_t *thread
 169: 	)
 170: {
 171: 	// パラメタの仮定
 172: 	ASSERT( IsValidWorkerThread( thread ) );
 173: 
 174: 	return ((DWORD)(-1)) != ResumeThread( thread->handle );
 175: }//ResumeWorkerThread
 176: 
 177: //*********************************************************
 178: // CancelWorkerThread
 179: //*********************************************************
 180: bool
 181: CancelWorkerThread
 182: 	(
 183: 		thread_t *thread
 184: 	)
 185: {
 186: 	// パラメタの仮定
 187: 	ASSERT( IsValidWorkerThread( thread ) );
 188: 
 189: 	// キャンセル機能なし
 190: 	if ( ! thread->heventCancel )
 191: 	{
 192: 		return false;
 193: 	}
 194: 
 195: 	// キャンセルを試みる
 196: 	const bool result = !! SetEvent( thread->heventCancel );
 197: 
 198: 	// キャンセルを認識できるようスレッドを起こす
 199: 	ResumeWorkerThread( thread );
 200: 
 201: 	// キャンセルを試みる
 202: 	return result;
 203: }//CancelWorkerThread
 204: 
 205: //*********************************************************
 206: // IsWorkerThreadFinished
 207: //*********************************************************
 208: bool
 209: IsWorkerThreadFinished
 210: 	(
 211: 		const thread_t *thread
 212: 	)
 213: {
 214: 	// パラメタの仮定
 215: 	ASSERT( IsValidWorkerThread( thread ) );
 216: 
 217: 	return IsSignalObject( thread->handle );
 218: }//IsWorkerThreadFinished
 219: 
 220: //*********************************************************
 221: // IsWorkerThreadCanceled
 222: //*********************************************************
 223: bool
 224: IsWorkerThreadCanceled
 225: 	(
 226: 		const thread_t *thread
 227: 	)
 228: {
 229: 	// パラメタの仮定
 230: 	ASSERT( IsValidWorkerThread( thread ) );
 231: 
 232: 	return IsSignalObject( thread->heventCancel );
 233: }//IsWorkerThreadCanceled
 234: 
 235: //*********************************************************
 236: // WaitWorkerThreadSignal
 237: //*********************************************************
 238: bool
 239: WaitWorkerThreadSignal
 240: 	(
 241: 		const thread_t *thread
 242: 	)
 243: {
 244: 	// パラメタの仮定
 245: 	ASSERT( IsValidWorkerThread( thread ) );
 246: 
 247: 	return WAIT_OBJECT_0 == WaitForSingleObject( thread->handle, INFINITE );
 248: }//WaitWorkerThreadSignal
 249: 
 250: 
 251: //******************************************************************************************************************
 252: // private
 253: //******************************************************************************************************************
 254: //*********************************************************
 255: // FinishWorkerThread
 256: //*********************************************************
 257: static
 258: bool
 259: FinishWorkerThread
 260: 	(
 261: 		thread_t *thread
 262: 	)
 263: {
 264: 	// パラメタの仮定
 265: 	ASSERT( IsValidWorkerThread( thread ) );
 266: 
 267: 	if ( ! IsWorkerThreadFinished( thread ) )
 268: 	{
 269: 		// 終了を要求
 270: 		CancelWorkerThread( thread );
 271: 
 272: 		// 終了できるようスレッドを起こす
 273: 		ResumeWorkerThread( thread );
 274: 
 275: 		// 終了するまで待つ
 276: 		WaitForSingleObject( thread->handle, INFINITE );
 277: 	}
 278: 
 279: 	return true;
 280: }//FinishWorkerThread
 281: 
 282: 
 283: //******************************************************************************************************************
 284: // private - callback
 285: //******************************************************************************************************************
 286: //*********************************************************
 287: // WorkerThreadProc
 288: //*********************************************************
 289: static
 290: DWORD // スレッドの終了コード
 291: WINAPI 
 292: WorkerThreadProc
 293: 	(
 294: 		void *param
 295: 	)
 296: {
 297: 	// パラメタの仮定
 298: 	ASSERT( IsValidWorkerThread( (thread_t *)param ) );
 299: 
 300: 	thread_t *thread = static_cast<thread_t *>( param );
 301: 	return thread->proc( thread, thread->param );
 302: }//WorkerThreadProc
 303: 
 304: 
 305: //** end **

参照:


Google
ご意見・ご感想をお聞かせ下さい。匿名で送信できます。

 * 返信が必要な場合には postmaster@katsura-kotonoha.sakura.ne.jp へ直接メールしてください。

水無瀬の部屋 > sample > tools > workthrd > workthrd.cpp

このページは cpp2web が出力しました。
水無瀬 優 postmaster@katsura-kotonoha.sakura.ne.jp
http://katsura-kotonoha.sakura.ne.jp/prog/code/tools/workthrd/workthrd_cpp.shtml
>> Amazon.co.jp 『たまゆら童子』 へ
>> 楽天ブックス 『たまゆら童子』 へ