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 */);