CriticalSectionの取り扱いを楽にするため、MFCのCCriticalSectionとCSimpleLockを使おうとして罠にハマったという話。
CCriticalSectionはCSemaphore等と異なりLock待ちのタイムアウトができない。そのため、ロックできなかったら諦める!という実装が不可能である。一方、CCriticalSection等を少し便利に使えるクラスCSimpleLockには、なんとIsLocked()という要求にピッタリマッチしてるっぽい関数があり、実装が可能なように見えたのだ。しかし、これは巧妙な罠だった。
実際に使ってみると・・・なんか・・・他スレッドでロック済みでもIsLocked()が0を返すんですが・・・。
そこでデバッグしてみた。まずはIsLocked()が何をやっているか?だ。定義はafxmt.inlにあるようだ。
をや。CCriticalSectionにはアクセスせずに、自前の変数:m_bAcquiredを見ているぞ?じゃあ、この変数はどんな定義だ?staticだったりするのか?
Definition of CSingleLock::m_bAcquired
をい。ただのメンバ変数じゃん。ということは、これは各オブジェクトのローカル変数なので、他スレッドでロックしているかどうかなんて全然見れないってこと?
だから公式のサンプルでは、ロックに成功しているかどうかの後チェックをする例なんて出してるのか。それならローカル変数で問題ない。
あきらめて、CriticalSectionではなくSemaphoreを使うことにしたorz
それにしてもCMultiLockの件といい、MFCのスレッド制御は何か残念だなあ。