FThreadバグ

スレッドキャンセル機構にバグがあった。修正。

実行中のスレッドをcancel()するのは問題ないのだが、既に終了しているスレッドのFThreadクラスインスタンスをcancel()すると既にfreeされたメモリを参照してしまう。

原因はスレッドキャンセルのフラグのdeleteをスレッド本体が行っていたため。

×:

  • 管理クラス: new フラグ
  • FThread::run() :Thread Specific Ptrにフラグへのポインタ入れる
  • スレッド終了: Thread Specific Ptrに入っているフラグをdelete
  • 管理クラス:フラグアクセス

○:

  • 管理クラス: new フラグ
  • FThread::run() :Thread Specific Ptrにフラグへのポインタ入れる
  • 管理クラス:フラグアクセス
  • 管理クラス: deleteフラグ

ここで、boost::thread_specific_ptrは、標準の挙動では自動でポインタをdeleteしてしまうので、なにもしないcleanup関数を定義してやり、コンストラクタに渡してやる。こんな感じ:

namespace
{
	void cleanup_dummy(bool*)
	{
		/* NOP */
	}
}

boost::thread_specific_ptr<bool> FThread::ms_tspbCancelled(cleanup_dummy /* do not delete the pointer */);